C++ 左值、右值、将亡值、纯右值、左值引用、右值引用、万能引用、移动语义、完美转发
左值
- 所有变量都是左值;
- =的左边;
- 可以&;
- 可以取下标[];
- 可以解引用;
- 前置递增递减运算符,++i,–i;
- 函数形参(void func(int &&a),这里a的类型是右值引用,a本身是左值);
右值
右值包括:将亡值、纯右值
- 临时变量;
- 常值;
- 有计算过程的表达式,比如a+1;
将亡值
T&&函数返回值,std::move返回值,将要被移动的对象等。
纯右值
非引用返回的临时变量,运算表达式产生的临时变量,原始字面量和lambda表达式等;
左值引用
使用符号 &
右值引用
使用符号 &&
移动语义(std::move)、完美转发(std::forward)、万能引用
#include <iostream>
using namespace std;
template <typename T>
void f(T&&a) //万能引用
{
/**万能引用
* 当传入的实参是右值,a的值类型为左值,a的类型为右值引用int&&,T被推导为int形式,即void f<int>(int && a);
* 当传入的实参是左值,a的值类型为左值,a的类型为左值引用int&,T被推导为int&形式,即void f<int&>(int &&& a)。引用折叠;
*/
std::move(a);·//直接将a从左值转为右值;
std::forward<T>(a);// 如果传入的实参是右值,则把a从左值转为右值;如果的实参是左值,则把a从左值转为左值;
}
int main()
{
f(5);
int i=5;
f(i);
return 0;
}
避免临时对象的产生
- 以传值的方式给函数传递参数;
- 类型转换生成临时对象;
- 隐式类型转换以保证函数调用成功;
- 函数返回对象的时候;
- 类外的运算符重载之中的优化;