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++ 限制类模板类型_C++_Templates_C++17_Sfinae - Fatal编程技术网

C++ 限制类模板类型

C++ 限制类模板类型,c++,templates,c++17,sfinae,C++,Templates,C++17,Sfinae,我试图使用SFINAE来限制我正在编写的类允许的模板参数类型。这里有一个简单的人为的例子,我想它说明了我想做什么 我确信这个问题已经在某处得到了回答,但我找不到答案 以下是我发现的两种解决问题的方法: 第一(SFINAE): 模板 类整数{ 公众: T值; }; int main(){ 整数i;//alowd 整数d;//不允许 整数dd;//允许(不需要) 返回0; } 我不喜欢这个解决方案的地方是,main函数中的第三个示例起作用 第二个(静态断言): #包括 模板 类整数{ 静态断言(s

我试图使用SFINAE来限制我正在编写的类允许的模板参数类型。这里有一个简单的人为的例子,我想它说明了我想做什么

我确信这个问题已经在某处得到了回答,但我找不到答案

以下是我发现的两种解决问题的方法:

第一(SFINAE):

模板
类整数{
公众:
T值;
};
int main(){
整数i;//alowd
整数d;//不允许
整数dd;//允许(不需要)
返回0;
}
我不喜欢这个解决方案的地方是,main函数中的第三个示例起作用

第二个(静态断言):

#包括
模板
类整数{
静态断言(std::is_same::value,“T必须是int”);
公众:
T值;
};
int main(){
整数i;//允许
整数d;//不允许
返回0;
}
我认为这个解决方案很好,但我想知道是否有一种更优雅或更简单的方法来完成同样的事情


在本例中,对于这个简单的示例,我希望能够强制执行模板类型T必须是整数。当然,在这种情况下,类甚至不需要是模板,我可以将Integer类中的类型声明为int类型,但我想在更复杂的情况下使用我在这里学到的内容。

您可以通过使用未命名的非类型模板参数修复第一个示例。改成

template <typename T, std::enable_if_t<std::is_same_v<T, int>, bool> = true>
class Integer {
public:
    T value;
};
模板
类整数{
公众:
T值;
};
只允许
整数i编译。它还阻止用户尝试使用
Integer dd绕过它

以另一种(右)方式使用SFINAE:

模板
类整数{
公众:
T值;
};

不再劫持。

C++20中会有一些概念。我发现
静态断言解决方案很好:如果您的类的用户尝试使用
整数
,他们会得到一个不错的编译错误,而不是一个丑陋的sfinae相关的文本墙。这里是否有一个过多的闭合角括号?我不确定哪一个是额外的。@Pavis11:Typo-fixed。在C++17问题中你得到了你的C++11!
#include <type_traits>

template <typename T>
class Integer {
    static_assert(std::is_same<T, int>::value, "T must be int");
public:
    T value;
};

int main() {
    Integer<int> i;    // Allowed
    Integer<double> d; // Not allowed

    return 0;
}
template <typename T, std::enable_if_t<std::is_same_v<T, int>, bool> = true>
class Integer {
public:
    T value;
};
template <typename T, typename std::enable_if<std::is_same<T, int>::value, int>::type = 0>
class Integer {
public:
    T value;
};