我目前正在编写一个小型辅助模板库,在将 std::enable_if
与模板参数一起使用时遇到了意外的不一致。
这些函数模板在 GCC 7.1 中编译良好:
template<typename T, std::enable_if_t<std::is_same_v<int, T>, T>* = nullptr>
void f() { };
template<typename T, std::enable_if_t<std::is_same_v<double, T>, T>* = nullptr>
void f() { };
int main()
{
f<int>();
f<double>();
}
而这些结构模板会产生编译错误:
template<typename T, std::enable_if_t<std::is_same_v<int, T>, T>* = nullptr>
struct f { };
template<typename T, std::enable_if_t<std::is_same_v<double, T>, T>* = nullptr>
struct f { };
int main()
{
f<int> x;
f<double> y;
}
错误:
main.cpp:36:70: error: template parameter ‘std::enable_if_t<is_same_v<int, T>, T>* <anonymous>’
template<typename T, std::enable_if_t<std::is_same_v<int, T>, T>* = nullptr>
^~~~~~~
main.cpp:40:12: error: redeclared here as ‘std::enable_if_t<is_same_v<double, T>, T>* <anonymous>’
struct f { };
^
我很难理解为什么编译器会提示这个结构:
- 第二个模板参数有默认值。
- 重新声明结构,即使两者具有不同的模板参数列表。
最佳答案
这是因为函数可以重载而 struct
不能。
- 对于函数,两种声明可以共存,并且
enable_if
通过 SFINAE 选择正确的重载。 - 对于
struct
,模板参数无关紧要。同名 => 重新声明。
关于c++ - 关于 SFINAE 的函数和结构之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51450850/