【C++】左值和右值,左值引用和右值引用
左值和右值,左值引用和右值引用 1.1 三类核心值类别 lvalue(左值) 特征:有 名字 ,通常可以 取地址 、可 重复引用 。 典型例子:变量名、解引用表达式。 int x = 1 ; int & r = x ; // x 是 lvalue int * p = & x ; // &x 合法 prvalue(纯右值) 特征:纯右值,通常是临时值,不保证具有可持久身份。 典型例子:字面量、临时对象、某些按值返回。 int y = 1 + 2 ; // (1 + 2) 是 prvalue std:: string s = "hi" ; // "hi" 转换后形成临时 prvalue xvalue(将亡值)(C++ 11) 特征:将亡值,有身份,但资源可被“接管”。 典型例子: std::move(x) 的结果、某些返回右值引用的表达式(如返回T&&类型的函数)。 std:: string a = "abc" ; std:: string b = std:: move ( a ); // std::move(a) 是 xvalue 2. std::move 不移动:它只是把左值变成右值(将亡值) 这句话是理解移动语义的支点。 std::move(x) 做的是 类型转换 :把 x 转成 T&& ,令表达式呈现 xvalue 性质。 真正的移动发生在:移动构造/移动赋值被选择并执行时。 这也解释了为什么在转发场景不能乱用 move :它会把原本的 lvalue 也强行当成可被移动的来源。 3. 引用折叠:把“转发引用”变成可计算规则 3.1 折叠发生在何处 当类型推导、 typedef/using 、模板实例化等导致“引用的引用”出现时,编译器会进行引用折叠。 例如: template < class T > void f ( T && x ); // T 发生推导,可能形成引用叠加 3.2 引用折叠四条规则(必须熟练) T& & -> T& T...