C++11 右值引用(4)std::forward

一 例子

先看一段代码,然后分析。

#include <iostream>

void out(int& t)
{
    cout << "out T&" << endl;
}

void out(int&& t)
{
    cout << "out T&&" << endl;
}


template<typename T>
void forward(T&& t)
{
    out(t);
    out(std::forward<T>(t));
    out(std::move(t));
}

cout << "forward---------------------------" << endl;
cout << "lvalue: " << endl;
int x = 2;
forward(x);

cout << endl;
cout << endl;

cout << "lvalue refer: " << endl;
int& y = x;
forward(y);

cout << endl;
cout << endl;

cout << "rvalue: " << endl;
forward(1);

cout << endl;
cout << endl;

cout << "rvalue refer: " << endl;
forward(std::move(x));

cout << endl;
cout << endl;
cout << "call out: " << endl;
int n = 1;
int& rn = n; 
out(1);
out(n);
out(rn);

结果如下:

forward---------------------------
lvalue:
out T&
out T&
out T&&


lvalue refer:
out T&
out T&
out T&&


rvalue:
out T&
out T&&
out T&&


rvalue refer:
out T&
out T&&
out T&&


call out:
out T&&
out T&
out T&

二 分析

首先介绍两个概念,右值转换和引用折叠原则。

(1) 模板函数参数T&&

若传递的是基本类型为A的左值,则T的类型为A&。

若传递的是基本类型为A的右值,则T的类型为A&&。

(2) 引用折叠原则

A& & 折叠成 A&

A& && 折叠成 A&

A&& & 折叠成 A&

A&& && 折叠成 A&&

(3) 分析

x和y为左值(y类型为左值引用,本身为左值),所以T为int&,则 t 为int& &&, 根据引用折叠,为int&

1和std::move(x)(std::move(x)返回类型为右值引用,本身为右值)为右值,所以T为int&&,则 t 为int&& &&, 根据引用折叠,为int&&

(4) std::forward

两个规则:

<1> Forwards lvalues as either lvalues or as rvalues, depending on T。

When t is a forwarding reference (a function argument that is an rvalue reference to a cv-unqualified function template parameter), this overload forwards the argument to another function with the value category it had when passed to the calling function.

<2> Forwards rvalues as rvalues and prohibits forwarding of rvalues as lvalues。

印证了前三项第二个输出。前三项第三个输出印证std::move的返回类型为右值引用。

前三项第一个和第二个输出印证了通过std::forward可以实现完美转发(参数传递保留左右值属性,且为引用,避免中间的消耗)。

三 注意

模板参数类型推导保留cv限定符(cv-qualifier,const和volatile限定符的统称)。

四 参考

cppreference

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值