左值和右值

可以将表达式分类为下列其中一个值类别:
lvalue(左值)
如果表达式未 const 限定,那么表达式可以出现在赋值表达式的左侧。
C++11XvalueC++11

要到期的 rvalue 引用。

C++11(Prvalue)C++11 rvalue
C++11非xvalueC++11 表达式 ,仅出现在赋值表达式的右侧。
C++11右值包括虚值和纯右值。 L值和x值可以称为泛型值。C++11
备注信息:
  • 班级 C++11(prvalue)C++11 右值可以是 cv 限定的,但不是类的 C++11(prvalue)C++11 右值不能具有 cv 限定资格。
  • 左值 C++11和右值C++11 可以是不完整类型,但右值 C++11 (纯右值)C++11 必须为完整类型或 void 类型。
对象是可以检查并存储到其中的存储区域。 左值 C++11或x值C++11 是指向此类对象的表达式。 lvalue 不一定允许修改它指定的对象。 例如, const 对象是无法修改的 lvalue。 术语 可修改的 lvalue 用于强调 lvalue 允许更改和检查指定的对象。 以下对象类型的 Lvalues 是不可修改的 lvalues:
  • 数组类型
  • 不完整的类型
  • const限定类型
  • 其成员之一符合 const 类型的结构或并集类型
因为这些lvalue是不可修改的,所以它们不能出现在赋值语句的左侧 仅限 C + +除非存在合适的赋值运算符仅限 C + +

仅限 CC将函数标识符定义为具有函数类型的表达式。 函数指示符与对象类型或 lvalue 不同。 它可以是函数的名称,也可以是取消引用函数指针的结果。 C语言在处理函数指针和对象指针时也有所区别。仅限 C

仅限 C + +返回左值引用的函数调用是左值。 表达式可以产生左值、 C++11瞬时值C++11C++11 (纯右值)C++11 右值,也可以不产生任何值。 仅限 C + +

某些 C++内置C++ 运算符需要左值作为部分操作数。 下表列出了这些操作程序及其用法的其他约束。
运算符 要求
& (unary) 操作数必须是左值。
++ -- 操作数必须为可修改的左值。 这适用于前缀和后缀表单。
= += -= *= %= <<= >>= &= ‸= |= 左操作数必须是可修改的 lvalue。

例如,所有赋值运算符都对其右操作数求值,并将该值赋给其左操作数。 左操作数必须是可修改的 lvalue。

地址运算符 (&) 需要 lvalue 作为操作数,而增量 (++) 和减量 (--) 运算符需要可修改的 lvalue 作为操作数。 以下示例显示了表达式及其相应的 lvalues。
表达式 lvalue(左值)
x = 42 x
*ptr = newvalue *ptr
a++ a
仅限 C + + f() f() 的函数调用
C++11
以下表达式是 xvalues:
  • 调用返回类型为 rvalue 引用类型的函数的结果
  • 强制类型转换为 rvalue 引用
  • 通过 xvalue 表达式访问的非引用类型的非静态数据成员
  • 一个指向成员访问表达式的指针,其中第一个操作数是 xvalue 表达式,第二个操作数是指向成员类型的指针
请参阅以下示例:
int a;
int&& b= static_cast<int&&>(a);

struct str{
   int c;
};

int&& f(){
   int&& var =1;
   return var;
}

str&& g();
int&& rc = g().c;
在此示例中, rvalue 引用 b 的初始化方法是 xvalue ,因为它是强制转换为 rvalue 引用的结果。 对函数 f() 的调用会生成 xvalue ,因为此函数的返回类型为 int&& 类型。 rvalue 引用 rc 的初始化方法是 xvalue ,因为它是通过 xvalue 表达式访问非静态非引用数据成员 c 的表达式。
C++11

仅限 CIBM 扩展当GNU C语言扩展启用时,复合表达式、条件表达式和强制转换可以作为左值,前提是其操作数是左值。

如果序列中的最后一个表达式是 lvalue ,那么可以指定复合表达式。 以下表达式等效:
(x + 1, y) *= 42;
x + 1, (y *=42);
地址运算符可以应用于复合表达式,前提是序列中的最后一个表达式是 lvalue。 以下表达式等效:
&(x + 1, y);
x + 1, &y;

如果条件表达式的类型不是空的,并且其 true 和 false 的分支都是有效的 lvalue ,那么条件表达式可以是有效的 lvalue。 如果操作数是 lvalue ,那么强制转型是有效的 lvalue。 主要限制是不能使用左值转换后的地址。 结束 IBM 扩展仅限 C