常量为C++中的右值(11)

Car*_*s00 10 c++ gcc c++11

为什么const int在C++中的R值(11)?我认为R值是'任何',它不能在左侧,常数可以实现.此代码失败:

int f(int && x) { return 100; }

void g() {
  const int x = 1;
  f(x);
}

error: invalid initialization of reference of type ‘int&&’ from expression
of type ‘const int’
Run Code Online (Sandbox Code Playgroud)

R. *_*des 12

好的,有三类表达式1:

  1. 表示具有身份且无法移动的对象的那些;
  2. 代表具有身份并可以移动的对象的那些;
  3. 那些代表没有身份并可以移动的对象的人;

第一个叫做左值,第二个叫xvalues,第三个是prvalues.如果我们将左值和x值放在一起,我们就有了glvalues.Glvalues是表示具有标识的对象的所有表达式.如果我们将xvalues和prvalues放在一起,我们就有rvalues.Rvalues是表示可以移动的对象的所有表达式.

有问题的表达式x是一个glvalue:一个人可以写&x,所以该对象显然具有一个身份.

我们可以摆脱这种表达吗?这个对象即将到期吗?不它不是.它只在当前表达式之后的某个时间到期.这意味着它无法移动.这使它成为一个左值.

所有这些名称都有点令人困惑,因为C++中的左值和右值不再意味着它们在C源中的含义.C++含义与赋值2的左侧或右侧完全无关.

就个人而言,我更喜欢使用Bjarne的本文中的术语:iM值(而不是左值),im值(而不是xvalues),Im值(而不是prvalues),i值(而不是glvalues),和m值(而不是rvalues).遗憾的是,这不是标准使用的术语.


1这里"有身份"的意思是"可以采取其地址"; "可以从"移动"意味着它即将到期,要么是由于它的临时性质,要么是因为程序员通过调用std::move或类似的东西在类型系统中明确表示.

2你可以在赋值的左侧有rvalues:std::vector<int>(17) = std::vector<int>(42)是一个有效的表达式,即使它是无用的.

  • @DeadMG:这可能会以非平凡的方式破坏现有代码.即使添加关键字也要仔细考虑,这会导致明显的编译错误.不会发生,IOW. (2认同)

Joh*_*ing 6

我认为R值是'任何',不能在[任务操作]的左侧

这就是C++ 03的定义rvalue,即使这样也是一种口语化,而不是普遍真实的.

在C++ 11中,定义lvaluervalue有所改变.规则很复杂,个别情况在标准中逐案处理,但这是一般的经验法则:

  1. 如果你能得到某些东西的地址,它就是一个 lvalue
  2. 如果表达式的类型是lvalue引用,则该表达式为lvalue
  3. 如果上述两者均不适用,则为 rvalue

在您的特定情况下,您可以获取x(例如,它"具有名称")的地址,因此它是左值.

您可以在两篇优秀文章中阅读有关C++ 11中左值和右值的更多信息: