c++ - enable_if用法 - enable_if



SFINAE工作在返回类型但不作为模板参数 (2)

您应该查看14.5.6.1 Function template overloading (C ++ 11标准),其中定义了函数模板等效。 简而言之,不考虑默认模板参数,因此在第一种情况下,您将定义两次相同的函数模板。 在第二种情况下,您有表达式引用返回类型中使用的模板参数(再次参见14.5.6.1/4)。 由于此表达式是签名的一部分,因此您将获得两个不同的函数模板声明,因此SFINAE有机会工作。

我已经使用了SFINAE习惯用了很多次,我习惯将std::enable_if<>放在模板参数中而不是返回类型中。 但是,我遇到了一些不起作用的琐碎案例,我不知道为什么。 首先,这是我的主要内容:

int main()
{
    foo(5);
    foo(3.4);
}

以下是触发错误的foo实现:

template<typename T,
         typename = typename std::enable_if<std::is_integral<T>::value>::type>
auto foo(T)
    -> void
{
    std::cout << "I'm an integer!\n";
}

template<typename T,
         typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
auto foo(T)
    -> void
{
    std::cout << "I'm a floating point number!\n";
}

这是一个可以正常工作的等效代码:

template<typename T>
auto foo(T)
    -> typename std::enable_if<std::is_integral<T>::value>::type
{
    std::cout << "I'm an integrer!\n";
}

template<typename T>
auto foo(T)
    -> typename std::enable_if<std::is_floating_point<T>::value>::type
{
    std::cout << "I'm a floating point number!\n";
}

我的问题是:为什么foo的第一个实现会触发该错误,而第二个实现不会触发它?

main.cpp:14:6: error: redefinition of 'template<class T, class> void foo(T)'
 auto foo(T)
      ^
main.cpp:6:6: note: 'template<class T, class> void foo(T)' previously declared here
 auto foo(T)
      ^
main.cpp: In function 'int main()':
main.cpp:23:12: error: no matching function for call to 'foo(double)'
     foo(3.4);
            ^
main.cpp:6:6: note: candidate: template<class T, class> void foo(T)
 auto foo(T)
      ^
main.cpp:6:6: note:   template argument deduction/substitution failed:
main.cpp:5:10: error: no type named 'type' in 'struct std::enable_if<false, void>'
          typename = typename std::enable_if<std::is_integral<T>::value>::type>
          ^

编辑

工作代码错误的代码


Answer #1

模板中的值有效:

template<typename T,
         typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
auto foo(T)
    -> void
{
    std::cout << "I'm an integer!\n";
}

template<typename T,
         typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0>
auto foo(T)
    -> void
{
    std::cout << "I'm a floating point number!\n";
}




sfinae