文章目录一、左值、右值与将亡值1、左值 (lvalue)2、右值 (rvalue)3、将亡值 (xvalue)4、左值引用 (lvalue reference)5、右值引用 (rvalue reference)6、右值引用本身是左值6.1、核心概念6.2、示例一、左值、右值与将亡值1、左值 (lvalue)是什么能取地址、有名字的值比如变量。特点可以放在等号左边比如a 10。例子inta10;// a是左值2、右值 (rvalue)是什么临时值不能取地址比如字面量、临时结果。特点只能放在等号右边比如10 a是错的。例子intb20;// 20是右值intcab;// (a b)的结果是右值3、将亡值 (xvalue)是什么介于左值和右值之间通常是“即将被移动”的值。特点可以被右值引用绑定资源会被“偷走”移动语义。例子std::string s1Hello;std::string s2std::move(s1);// s1变成将亡值内容被移动到s2注意将亡值是右值的一种。4、左值引用 (lvalue reference)是什么用声明的引用只能绑定左值。用途别名修改原变量。例子inta10;intrefa;// ref是a的别名ref20;// 修改a的值5、右值引用 (rvalue reference)是什么用声明的引用只能绑定右值或将亡值。用途实现移动语义避免拷贝直接“偷”资源。例子std::string s1Hello;std::string s2std::move(s1);// std::move(s1)返回右值引用6、右值引用本身是左值在C中右值引用(T)变量本身实际上是一个左值这看起来似乎矛盾但理解这一点对掌握移动语义和完美转发至关重要。6.1、核心概念右值引用的本质右值引用是可以绑定到右值的引用类型但一旦绑定后这个引用变量本身是一个具名对象因此是左值为什么是左值voidfoo(intrref){// rref 在这里是左值因为它// 1. 有名字 (rref)// 2. 可以取地址 (rref)// 3. 可以出现在赋值左侧}6.2、示例voidprocess(int){std::coutlvalue\n;}voidprocess(int){std::coutrvalue\n;}templatetypenameTvoidrelay(Targ){process(arg);// 总是调用左值版本process(std::forwardT(arg));// 根据原始类型调用}intmain(){intx10;relay(x);// 传入左值relay(20);// 传入右值}输出lvalue lvalue lvalue rvalue一句话总结左值有名字的变量右值临时的值将亡值快被移动的值。左值引用 ()操作原变量右值引用 ()高效“偷”资源。