SFINAE工作在返回类型,但不作为模板参数 [英] SFINAE working in return type but not as template parameter

查看:191
本文介绍了SFINAE工作在返回类型,但不作为模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用了SFINAE成语了很多次,我习惯了在模板参数而不是返回类型中放置我的 std :: enable_if<> 。然而,我遇到一些小事情,它没有工作,我不知道为什么。首先,这里是我的主要:

I already used the SFINAE idiom quite a few times and I got used to put my std::enable_if<> in template parameters rather than in return types. However, I came across some trivial case where it didn't work, and I'm not sure why. First of all, here is my main:

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 integrer!\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";
}

这是一个假设的等效代码片段:

And here is a supposedly equivalent piece of code that works fine:

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";
}


$ b < foo 触发该错误,而第二个不触发它?

My question is: why does the first implementation of foo triggers that error while the second one does not trigger it?


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>
          ^


EDIT

工作代码错误代码

推荐答案

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

You should take a look at 14.5.6.1 Function template overloading (C++11 standard) where function templates equivalency is defined. In short, default template arguments are not considered, so in the 1st case you have the same function template defined twice. In the 2nd case you have expression referring template parameters used in the return type (again see 14.5.6.1/4). Since this expression is part of signature you get two different function template declarations and thus SFINAE get a chance to work.

这篇关于SFINAE工作在返回类型,但不作为模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆