Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 创建模板<;T>;仅适用于具有运算符/定义的T_C++_Templates_Operators - Fatal编程技术网

C++ 创建模板<;T>;仅适用于具有运算符/定义的T

C++ 创建模板<;T>;仅适用于具有运算符/定义的T,c++,templates,operators,C++,Templates,Operators,我想为类型定义一个模板,但我必须确保只有定义了运算符和运算符+的类型才能作为T传递 这是因为我希望能够获得其中两个(类型相同)的插值,例如: 模板 最终类密钥:公钥库{ public://以保持示例的简单性 //unsigned timeMS;如果您想要一条不包含通过ADL或类似方法找到的运算符的双精度的好错误消息,您可以定义特征: template <typename, typename=void> struct isAddable : std::false_type {}; t

我想为类型定义一个
模板
,但我必须确保只有定义了
运算符
运算符+
的类型才能作为
T
传递

这是因为我希望能够获得其中两个(类型相同)的插值,例如:

模板
最终类密钥:公钥库{
public://以保持示例的简单性

//unsigned timeMS;如果您想要一条不包含通过ADL或类似方法找到的运算符的双精度的好错误消息,您可以定义特征:

template <typename, typename=void>
struct isAddable : std::false_type {};

template <typename T>
struct isAddable<T, decltype(void(std::declval<T>() + std::declval<T>()))>
    : std::true_type {};

template <typename, typename=void>
struct isDividable : std::false_type {};

template <typename T>
struct isDividable<T, decltype(void(std::declval<T>() / std::declval<T>()))>
    : std::true_type {};
模板
结构isAddable:std::false_type{};
模板
结构不可编辑
:std::true_type{};
模板
结构是可划分的:std::false_type{};
模板
结构可划分
:std::true_type{};
…并使用静态断言

static_assert( isAddable<T>{} && isDividable<T>{}, "Invalid T!" );
static_断言(isAddable{}&&isdiviable{},“无效的T!”);
或者,要获得更具体的信息:

static_assert( isAddable<T>{}, "T not addable!" );
static_assert( isDividable<T>{}, "T not dividable!" );
static_断言(isAddable{},“T not addable!”);
静态_断言(isdiviable{},“T不可分割!”);


你也可以使用一个方便的宏来定义这些特征

#define VAL std::declval<T>()

#define DEF_TRAIT(name, expression)                                  \
template <typename, typename=void> struct name : std::false_type {}; \
template <typename T>                                                \
struct name<T, decltype(void(expression))> : std::true_type {};

DEF_TRAIT(isDividable, VAL / VAL)
DEF_TRAIT(isAddable, VAL + VAL)
#定义VAL std::declval()
#定义定义特征(名称、表达式)\
模板结构名称:std::false_type{}\
模板\
结构名称:std::true_type{};
定义特性(可划分,VAL/VAL)
定义特征(isAddable,VAL+VAL)

.

如果在未定义该运算符的类的实例上使用该运算符,则会出现编译错误。因此,该类型受到隐式约束。如果未定义这些运算符,您希望它做什么?@GézaTörök我同意。不过,我希望在创建此类对象时出现错误(从我的观点来看,甚至声明它都是毫无意义的),而不是等待操作符使用它。@MarkB我想最好生成一个编译时错误。这太棒了:)先生,感谢您提供了包含演示的详细答案。这将检查
T/T
T+T
是否有效,但如果不是为同一类型的两个对象进行重载,则会失败。@0x499602D2不相关。问题说明“这是因为我希望能够获得其中两个对象的插值。”(属于同一类型的),”
#define VAL std::declval<T>()

#define DEF_TRAIT(name, expression)                                  \
template <typename, typename=void> struct name : std::false_type {}; \
template <typename T>                                                \
struct name<T, decltype(void(expression))> : std::true_type {};

DEF_TRAIT(isDividable, VAL / VAL)
DEF_TRAIT(isAddable, VAL + VAL)