第十三章:右值引用

1.对右值进行绑定的引用就是右值引用

T &&rr = 右值;
1.1 右值引用的创建目的

①解决临时对象非必要的昂贵的拷贝操作
②在模板函数中能够按照参数的实际类型进行转发

1.2 什么是右值

区分左值和右值的简单办法:

  • 看能不能对表达式取地址,如果能,则为左值,否则为右值
  • 所有的具名变量或对象都是左值,而匿名变量则是右值

右值种类:

int i = getVar();			//①非引用返回的临时变量
int i = 2*3+j;   			//②运算表达式产生的临时变量
int i = 0;       			//③原始字面量
auto f = [](){return 6;};	//④lambda表达式
1.3 右值引用
T&& k = getVar();           
/*k为右值引用,此时getvar()产生的临时值会被“续命”,它的生命周期将会通过右值得以延续,和变量k的声明周期一样长。*/
  • 常量左值引用是一个“万能”的引用类型,可以接受左值、右值、常量左值和常量右值
  • 普通的左值引用不能接受右值
  • T&& t在发生自动类型推断的时候,它是未定的引用类型(universal references),如果被一个左值初始化,它就是一个左值;如果它被一个右值初始化,它就是一个右值,它是左值还是右值取决于它的初始化。
template<typename T>
void f(T&& t);
f(10); //t是右值
int x = 10;
f(x); //t是左值

2.移动构造函数

当以右值作为参数传入时,会调用类的移动构造函数

A(A&& a)
{
	...
	cout << "move construct" << endl;
}

std::move方法来将左值转换为右值,从而方便应用移动语义。move是将对象资源的所有权从一个对象转移到另一个对象,只是转移,没有内存的拷贝,这就是所谓的move语义。

{
	std::list<std::string> tokens;                 //省略初始化...
	std::list<std::string> t = tokens;             //这里存在拷贝
}
	std::list<std::string> tokens;
	std::list<std::string> t = std::move(tokens);  //这里没有拷贝

move语义的拷贝构造函数和赋值函数,避免无谓的深拷贝,以提高性能。事实上,C++11中所有的容器都实现了移动语义,方便我们做性能优化。
  一些基本类型比如int和char[10]定长数组等类型,使用move的话仍然会发生拷贝(因为没有对应的移动构造函数)。所以,move对于含资源(堆内存或句柄)的对象来说更有意义。

3.参数转发

C++11引入了完美转发:在函数模板中,完全依照模板的参数的类型(即保持参数的左值、右值特征),将参数传递给函数模板中调用的另外一个函数。C++11中的std::forward正是做这个事情的,他会按照参数的实际类型进行转发。

void processValue(int& a){ cout << "lvalue" << endl; }
void processValue(int&& a){ cout << "rvalue" << endl; }
template <typename T>
void forwardValue(T&& val)
{
	processValue(std::forward<T>(val)); //照参数本来的类型进行转发。
}
void Testdelcl()
{
	int i = 0;
	forwardValue(i); //传入左值
	forwardValue(0);//传入右值
}
输出:
lvaue
rvalue

右值引用T&&是一个universal references,可以接受左值或者右值,正是这个特性让他适合作为一个参数的路由,然后再通过std::forward按照参数的实际类型去匹配对应的重载函数,最终实现完美转发。
  
来源: qicosmos(江南) - 博客园 
链接:从 4 行代码看右值引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值