C++11特性 万能引用 引用折叠

万能引用:

说人话就是这个引用即能引用左值又能引用右值

分为两种:

        1. const 左值引用

我们知道,变量的操作都可以概括为读和写,读要求变量的右值属性即可,写则要求变量的左值属性,const引用显然不允许写操作,因此无论左值还是右值都可以绑定上去,(实际上绑定右值相当于拷贝了一份临时变量再绑定)

        2. 编译时多态类型的右值引用

编译时多态有两种体现形式,一种是模板,一种是auto和decltype(decltype并不能形成万能引用,但与下面要讲的引用折叠息息相关)

C++ 之后的很多版本都对auto 和decltype进行了拓展,已经很好的能替代模板的一部分功能,这里举个例子:

/*
    设计一个进行+操作的方法
*/
//first  C中可以拿宏嘛  缺点就是宏函数并不能体现C++的特性,编写麻烦(少个括号就GG),而且其作用域不可控的特性不利于大规模工程开发
#define sum(x,y) ((x)*(y))
//second 当然是模板啦 缺点显而易见 复杂的模板参数,而且在使用时还需要指定结果类型,这不是扯淡嘛,明明编译器都能帮我们干
template<typename sum1T,typename sum2T,typename resultT>
resultT sum(sum1T s1,sum2T s2){
    return s1+s2;
}
//third 使用decltype+模板
template<typename sum1T,typename sum2T>
decltype(*static_cast<sum1T*>(nullptr)+*static_cast<sum2T*>(nullptr)) sum(sum1T s1,sum2T s2){
    return s1+s2;
}
//or    declval返回指定类型的右值引用(不管是否有默认构造方法) 其实等效于上面的操作
template<typename sum1T,typename sum2T>
decltype(declval<sum1T>()+declval<sum2T>()) sum(sum1T s1,sum2T s2){
    return s1+s2;
}
//注意下面这种写法是不完善的  
template<typename sum1T,typename sum2T>
decltype(sum1T()+sum2T()) sum(sum1T s1,sum2T s2){  //原因显而易见 sum1T sum2T不一定有默认构造方法
    return s1+s2;
}
//forth 使用后置返回值+decltype+auto形式彻底摆脱模板
auto sum(auto s1,auto s2)->decltype(s1+s2){
    return s1+s2;
}
//fifth 终极简化 完全删去decltype
auto sum(auto s1,auto s2){
    return s1+s2;
}

回归正题:

T&& or auto&& 都是万能引用

  1. 注意这个万能是初始绑定万能,一旦确定其左右值属性就不能再更改了
  2. 推导时那个T/auto被替换为{左值 T&  右值 T} 

引用折叠

C++不允许引用的引用这一说法,但第二类万能引用 and decltype很可能产生引用叠加问题

如:

//auto/模板
void test(auto &&x){
}

int main(){
    int b=10;
    test(10) //->相当于 int &&正常
    test(b); //->相当于int& && 不正常了,出现左值的右值了  这时我们把左值的右值换为左值 即相当于int &
    int&& c =15;
    int&d =b;
    decltype(c) &&e = xxx;//->相当于int&& && 右值引用的右值引用 替换为右值引用 即int&&
    decltype(c) &f=xxx;//右的左->左
    decltype(d) &g=xxx;//左的左->左
}

总结一句话就是 只有右的右是右值引用 其他都是左

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值