C++ Primer(第五版)第471页在右值引用这一小节提到,可以将一个const的引用(左值引用)绑定到一个右值上。
那么为什么常量引用会有这一特性?
为了解释这一疑问,可以从C++ Primer的第55页找到答案:
- 引用的类型必须与其所引用的对象的类型一致,例外是在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果可以转换为引用的类型即可。
int i = 42;
const int &r1 = i; //允许将const int&绑定到一个普通的int对象
const int &r2 = 42; //正确:r2是一个常量引用 此时绑定的是右值
const int &r3 = r1 * 2; //正确:r3是一个常量引用 此时绑定的是右值
int &r4 = r1 * 2; //错误:r4是一个普通的非常量引用
我们这里必须要搞清楚当一个常量引用绑定到一个右值的时候发生了什么,才能够解释上述现象
const int &ri = 42; //以这个为例,解析常量引用绑定到右值时到底发生了什么
/////////////////////////////////
const int temp = 42; //编译器生成一个临时整形常量
const int &ri = temp; //ri绑定的是这个临时量
由上段代码可以看出,当常量引用绑定的是一个右值时,实际上绑定的是一个临时量。由于ri是常量引用,那么绑定一个临时量也不会有什么问题,因为无法通过ri修改引用想要绑定的对象(这里是右值,看上去像是绑定了右值)。如果ri不是常量引用,就允许对ri赋值,这样就会改变ri所引用对象的值,就算改了也只是改了临时量temp的值,没有任何意义,所以C++就把这种行为归为非法。