Rvalues vs temporaries

时间:2010-07-09 14:30:26

标签: c++

有人概括了“Temporaries is rvalues”的说法。我说“不”并给了他以下例子

 double k=3;

 double& foo()
 {
    return k;
 }

 int main()
 {

     foo()=3; //foo() creates a temporary which is an lvalue
 }

我的解释是否正确?

3 个答案:

答案 0 :(得分:9)

Temporaries和rvalues是不同的(但相关的)概念。暂时是对象的属性。非临时对象的示例是本地对象,全局对象和动态创建的对象。

作为右值是表达式的属性。与右值相反的是左值,例如名称或解引用指针。 “Temporaries is rvalues”这句话毫无意义。这是rvalues和临时对象之间的关系:

  

rvalue是一个表达式,其求值会创建一个临时对象,该对象在词法包含rvalue的full-expression结束时被销毁。

请注意,左值也可以表示临时对象!

void blah(const std::string& s);

blah(std::string("test"));

在函数blah中,左值s表示通过计算表达式std::string("test")创建的临时对象。

你的评论“引用是左值”也没有意义。引用不是表达式,因此不能是左值。你的真正含义是:

  

如果函数返回引用,表达式 function()是左值。

答案 1 :(得分:7)

没有。您将返回对全局double的引用,而不是临时的。

与真实临时的相同测试将是:

double foo() { return 3.0; }
int main() {
   foo() = 2.0; // error: lvalue required as left operand of assignment
}

编辑: 答案只是为了确定这个例子是错误的,我真的不想进一步深入讨论临时性是否是rvalues ......正如其他人所说的那样,左值或右值是属性表达而不是对象(在最一般意义上,不仅是类实例)。然后,标准说:

  

§3.10/ 5调用不返回引用的函数的结果是rvalue。用户定义的运算符是函数,这些运算符是否期望或产生左值是由它们的参数和返回类型决定的。

     

§3.10/ 6保存由非强制类型转换产生的临时对象的表达式是一个右值(这包括使用功能表示法显式创建对象(5.2.3))。

哪种AFAIK是创造临时性的环境。现在,您也可以将常量引用绑定到临时引用,在这种情况下,您将获得一个新变量(引用),该变量可用作有效引用临时对象的左值。

细则是创建临时表达式的表达式是rvalue表达式。您可以将常量引用绑定到该表达式的结果,以获取可用作const限定左值表达式的变量。

答案 2 :(得分:0)

Temporaries一直受到保护,不会成为左撇子,他们现在被称为左撇子。但是由于移动语义,C ++ 0x将允许临时值变为左值。就像在这个愚蠢的片段

void blah(ICanBeTemporary && temp)
{
    temp.data = 2; //here temporary becomes lvalue
}


//somewhere
blah(ICanBeTemporary("yes I can"));

现在我们的术语一团糟。人们习惯称之为临时值rvalues,这称为右值参考。现在,命名对象被认为是非右值引用。