SFINAE 极简介绍

首先推荐讲SFINAE我认为最好的两个资料,一个是cppreferenceSFINAE,一个是channel9上Stephan T Lavavej讲的三个series:Core CPP,STL, Advacned STL其中的某一集。。。的确忘了是哪集了。这两个资料有深入有浅出,最重要的是讲明白了SFINAE的本质,而不是上来就一段代码告诉你这个就是SFINAE,看完了就看完了而已,完全和其他知识联系不起来。。。


推荐完资料,下面试着用最简单的方式来说清楚SFINAE。
SFINAE全名是"Substitution Failure Is Not An Error"。具体应用于构建function overload resolution set时候的template specialization。由于重载的存在,当编译期决定函数调用的时候,其实是先构建了一个重载函数候选的集合,然后在根据标准里的规则选出最佳的调用函数。如果存在function template,在构建这个集合的时候,编译器就开始进行模板特化。模板特化也就不可避免的涉及到类型操作。如果模板参数里面的某个类型替换失败,则这个模板特化失败,继续向下进行,而不是引起编译错误,这就是“替换失败并非错误”的本意了。
从这个解释可以看出,如果我们有意的控制模板特化时候的失败,就可以控制哪些特化可以进入重载候选集合,哪些特化直接被忽略掉,从而控制overload resolution的结果,成为编译期语言C++的一大利器。。。


最基本的差不多解释清除了,下面看代码。先是最简单的enable_if:

  template<bool, typename _Tp = void>
    struct enable_if
    { };   
           
  // Partial specialization for true.
  template<typename _Tp>
    struct enable_if<true, _Tp>
    { typedef _Tp type; };

可以看到,只有bool为true的时候,enable_if才会存在一个enable_if::type类型。

来自于cppreference的例子:

template<class T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type 
    foo1(T t) 
{
    std::cout << "foo1: float\n";
    return t;
}

如果T不是float,double什么的,这个模板函数可以直接当作不存在。

在enable_if的源码下面,还有:

  template<typename... _Cond>
    using _Require = typename enable_if<__and_<_Cond...>::value>::type;

利用enable_if和varadic template来对多个条件进行判断。

有空在补一点复杂些的代码。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值