在rvalue和左值之间转换

时间:2017-10-31 16:51:00

标签: c++ rvalue lvalue

我试图理解并读到rvalues无法转换为左值。以下是好的

int x = 1;     // x is an lvalue
int y = 2;     // y is an lvalue
int z = x + y; // the "+" needs rvalues, so x and y are converted to rvalues 
               //(from lvalues) and an rvalue is returned

现在,如果我这样做

x = 5;
y = 6;

不是x和y转换为左值(来自rvalues)吗?

编辑:What are rvalues, lvalues, xvalues, glvalues, and prvalues?中的问题几乎没有提及转换,也没有解释的例子。

2 个答案:

答案 0 :(得分:1)

准确了解我们正在谈论的内容非常重要。

  • 在C ++中,表达式有一个类型,可以是左值或右值(值类别
  • 当一个表达式(类型,值类别)出现在需要不同(类型,值类别)的上下文中时,会发生隐式转换
  • 显式转换使用其中一种语言的强制转换运算符,将子表达式(类型,值类别)作为操作数,并生成不同的表达式(类型,值类别)结果。

左值或x值可以隐式转换为prvalue;由于历史原因,这称为左值到右值的转换。这条线

int z = x + y;

用作此隐式转换的示例。正如评论所解释的那样,内置的+运算符期望prvalues作为其操作数,但我们提供了左值,因此会发生隐式转换。

左值也可以显式转换为xvalue:

std::string s1 = static_cast<std::string&&>(s2);  // i.e., std::move(s2)

这里s2是左值,但是我们要确保初始值设定项是xvalue,以便使用移动构造函数,因此我们执行显式转换。

rvalue既不能隐式也不能显式转换为左值。例如,以下内容无法编译:

3++;

因为++运算符需要左值,我们提供了一个右值。以下编译也是如此,我们尝试将rvalue显式转换为左值:

static_cast<int&>(3)++;

(注意:3的类型为int,而不是const int。常量我们无法修改3的原因。 )

在显示的分配中实际上没有发生转换:

x = 5;
y = 6;

因为在分配int左值时,prvalue 预期作为右手操作数,而prvalue已提供。虽然我们正在进行某种操作,其中rvalue作为源,左值作为目标,但根据语言规则,这不是转换

答案 1 :(得分:-1)

Lvalue有点意味着&#34;地址&#34;。 Rvalue有点意味着&#34;价值&#34;。 表达式是左值或右值。由于表达式x是左值,但在表达式z = x + y;中,+运算符需要数据,因此xy将被取消引用。也就是说,它们的地址处的值被取出,并且这些rvalue值被加在一起,产生的rvalue等于它们的总和。赋值运算符左侧需要左值,右侧需要右值。它将右侧的值放入左侧的地址中,因此z未被解除引用,并且是左值。

在知道其上下文之前,不能说像x这样的变量是左值或左值。