关于SFINAE的功能和结构之间的差异

时间:2018-07-20 21:53:25

标签: c++ templates

我目前正在编写一个小的帮助程序模板库,并且在将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 { };
        ^

我正在努力理解为什么编译器会抱怨该结构:

  1. 第二个模板参数有一个默认值。
  2. 即使两个结构体都有不同的模板参数列表,也要重新声明该结构体。

1 个答案:

答案 0 :(得分:1)

这是由于可以重载函数而struct不能重载。

  • 对于函数,两个声明可以共存,并且enable_if通过SFINAE选择正确的重载。
  • 对于struct,模板参数无关紧要。同名=>重新声明。