C/C++ 关于enable_if及重载选择的问题

遇到了enable_if问题以及相关的概念,这里做一下总结;

基本概念:

enable_if主要的作用是模板类型推导,用于选择重载的版本;

这里先说一下SFINAE,因为enable_if所用的也是SFINAE特性;

1.SFINAE概念:

全称为:Sbusitution Failure Is Not An Error;

用人话说的意思就是,如果有多个重载函数,不能匹配的重载函数看作删除,而不作为错误;

在重载时,会先利用该参数进行所有候选函数的推导,来得到一个完美的匹配;

但是对于不能匹配的无效模板参数,则会从重载决意集合中删除,而不是报错;

2.enable_if作用:

enable_if更多的可以看作一种swtich选择条件,源码如下所示:

// STRUCT TEMPLATE enable_if
template <bool _Test, class _Ty = void>
struct enable_if {}; // no member "type" when !_Test

template <class _Ty>
struct enable_if<true, _Ty> { // type is _Ty for _Test
    using type = _Ty;
};

总的来书也是模板泛化,但是包含普适和特例两种情况;

接受两个模板参数,判断条件_test布尔值,_Ty类型值;

可以看到,由于特例化的存在,只有当_test为真时,内部才有type,否则使用enable_if<T1,T2>::type为未定义类型;

再提一下typename的问题;

typename 可以视为class的拓展,但是不局限于使用在template声明中,而是可以告知某个变量是类型还是类内成员;

例如:

template<typename T>
void fun(const T& proto){


        T::const_iterator it(proto.begin());
}

上述代码并不能通过编译,根本原因是不能分辨T::const_iterator是类型还是类内成员;

因此需要在前面加上:

typename T::const_iterator it(proto.begin());

告知编译器T::const_iterator是一个类型,而非类内成员,it则是该类型下的声明的一个变量;

具体例子:

这里参照网上和书本示例:

template<typename T>
typename std::enable_if<std::is_integral<T>::value,T>::type ret(T k) {
    cout << "this is int type" << endl;
    return k;
}

template<typename T>
typename std::enable_if<std::is_same<T, double>::value, T>::type ret(T k) {
    cout << "this is double version" << endl;
    return k;
}

上段代码定义了ret()函数的两个版本;

第一个为int版本,第二个为double版本;

注意一下内部的判断bool泛型:is_integral<T>is_same<T,U>

在这里插入图片描述

在这里插入图片描述
前者判断是否为int,后者判断泛型型别是否相同;

typename std::enable_if<condition,T>::type ret(T k) {
    return k;
}

enable_if可以根据T的类型进行判断,从而选择和自己类型指定的重载函数;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值