值类别 (value category)#
- 左值
可以概括认为是已经存在了的对象, 例如:
所有有名字的对象 (
int value
).字符串字面值 (
"hello"
, 它 存储在一个特殊区域).
左值实际存在, 这意味着它被存储在某个位置, 则可以通过
&
获取它的地址:1int value; 2std::cout << &value; // 获取地址并输出
- 右值
除了左值以外的值, 例如:
临时对象 (
int function()
的返回值).其他字面值 (
42
, 它即写即用, 不会被存储).
警告
这里的解释是通用解释, 实际表现可能由于编译器、编译器版本、编译选项、标准版本等存在差异.
交叉内容#
值类别与引用#
T&
只能引用左值即 "已经存在的对象", 因此不进行会产生临时对象的隐式类型转换.
1int value = 0;
2int& reference = value;
1double value = 0;
2int& reference = value; // 错误: double 隐式类型转换为 int 是产生新的临时对象
1class A {};
2class B : public A {};
3
4B b;
5A& = b; // 正确: 基类引用兼容派生类
T const&
既能引用左值又能引用右值.
既然能引用右值即临时值, 则允许在引用时发生隐式类型转换; 但这将会引用转换产生的临时对象而不是原本的对象.
1double value = 0;
2int const& reference = value; // 正确: T const& 能够引用临时对象
3
4value = 1;
5std::cout << reference; // 输出 0