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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于SFINAE的功能和结构之间的差异相关的知识,希望对你有一定的参考价值。

我正在编写一个辅助模板的小型库,当使用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. 即使两者都具有不同的模板参数列表,也会重新声明该结构。
答案

这是因为函数可以重载,而structs则不能。

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

以上是关于关于SFINAE的功能和结构之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

平均情况和摊销分析之间的差异

是否可以混合 SFINAE 和模板专业化?

elasticsearch vs solr 关于数据结构/查询功能

g++ 和 clang++ 使用变量模板和 SFINAE 的不同行为

活动和片段之间有啥区别?

ManActivity + 启动时的片段差异