猿问

请问工作在返回类型但不作为模板参数的SFINAE

工作在返回类型但不作为模板参数的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>
          ^

编辑 :

工作代码错误码.


哆啦的时光机
浏览 444回答 3
3回答

喵喔喔

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

千万里不及你

模板中的值工作:template<typename&nbsp;T, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;std::enable_if<std::is_integral<T>::value,&nbsp;int>::type&nbsp;=&nbsp;0>auto&nbsp;foo(T) &nbsp;&nbsp;&nbsp;&nbsp;->&nbsp;void{ &nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;"I'm&nbsp;an&nbsp;integer!\n";}template<typename&nbsp;T, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typename&nbsp;std::enable_if<std::is_floating_point<T>::value,&nbsp;int>::type&nbsp;=&nbsp;0>auto&nbsp;foo(T) &nbsp;&nbsp;&nbsp;&nbsp;->&nbsp;void{ &nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;"I'm&nbsp;a&nbsp;floating&nbsp;point&nbsp;number!\n";}
随时随地看视频慕课网APP
我要回答