移动语义是 C++11 里引入的一个重要概念。在理解移动语义之前,需要先了解 C++ 表达式中的左值右值。
在C++标准中,定义了如下值类别 ( value categories )
通常,左值 lvalue 是有标识符、可以取地址的表达式,最常见的情况有:
在函数调用中,左值可以绑定到左值引用的参数,如 T&。一个常量只能绑定到常左值引用,如 const T&。
void func1(int & v) {}
void func2(const int & v) {} // 如果这里接收参数类型是 const int &, 无法编译
int a = 0;
const int b = 0;
func1(a); // a是左值,绑定到左值引用
func2(b);
纯右值 prvalue 是没有标识符、不可以取地址的表达式,一般也称之为“临时对象”。最常见的情况有:
<aside> 💡 可以理解为 a 这个对象 就是左值,a 这个对象内的内容,就是右值
</aside>
在 C++11 之前,右值可以绑定到常左值引用(const lvalue reference)的参数,如 const T&,但不可以绑定到非常左值引用(non-const lvalue reference),如 T&。从C++11 开始,C++ 语言里多了一种引用类型——右值引用。右值引用的形式是 T&&,比左值引用多一个 & 符号。
<aside> 💡 不要理解为是 引用的引用
</aside>