代码之家  ›  专栏  ›  技术社区  ›  Fibbs Kerrek SB

函数和结构在SFINAE方面的差异

  •  0
  • Fibbs Kerrek SB  · 技术社区  · 8 年前

    我目前正在编写一个小的助手模板库,在使用 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 回复  |  直到 8 年前
        1
  •  1
  •   mpark    8 年前

    这是因为函数可以重载,而 struct s不能。

    • 对于函数,两个声明都可以共存。 enable_if 通过SFINAE选择正确的过载。
    • 为了 结构 模板参数不重要。同名=>重新声明。