函数返回值是否默认为常量(右值)?

时间:2011-12-11 22:09:54

标签: c++ constants return-value rvalue

我正在学习右值参考,教程告诉我:

X foo();
X x;
x = foo();
     很明显,在x和x之间交换资源指针(句柄)会更好,也更有效率   临时的,然后让临时的析构函数破坏x的原始资源。

     

换句话说,在右侧的特殊情况下   赋值是一个右值,我们希望复制赋值运算符起作用   像这样。

那么,这是否意味着函数的返回值在默认情况下始终是常量,从而是一个rvalue?如果是:它们总是不变,还是有例外?

5 个答案:

答案 0 :(得分:3)

  

那么,这是否意味着函数的返回值在默认情况下始终是常量,从而是一个rvalue?如果是:它们总是不变,还是有例外?

没有。如果他们没有返回引用类型(cv T&cv T&&),则它们是rvalues。如果它们的返回类型是const限定的,它们是常量。

这意味着函数X foo()的返回值是rvalue(prvalue,如果你想要 new standardese ),而不是常量。此外,在像x = foo()这样的表达式中,我们通常不关心赋值期间的临时变化,这几乎是移动语义背后的想法。

答案 1 :(得分:3)

Rvalue-ness和constant-ness不是同义词,而是有点正交。具有以下定义:

struct X {};
const X x;
const X f();
int X();

我们可以对以下表达式进行分类:

x;       // constant lvalue
f();     // constant rvalue
g();     // non-constant rvalue

截至您的特定问题:不,并非所有的右值表达式都是常量。

答案 2 :(得分:1)

您可能会混淆类型对象表达式。只有表达式具有左值/右值的概念。 表达式 foo();X类型的右值。因此,语句x = foo();将调用 - 如果可能 - X::operator=(X &&)的成员函数x。如果失败了,它将绑定到标准X::operator=(X const &),因为rvalues绑定到const-references。

请注意,理论上可以使用常量rvalues,例如,如果您将函数声明为X const bar();。然后,bar()不会绑定到X&&,而只会绑定到X const &&(以及X const &)。但是,在实践中没有用这个。

答案 3 :(得分:1)

参见this previous question,它告诉我们rvalue表达式既不是const类型的隐式表达式,也不是它们所代表的对象本身也是不可变的。

但是, 未定义(或禁止 - 我忘记了哪些)在某些情况下通过右值修改对象。这似乎产生了一种通过rvalue访问的对象的条件固有的不变性,并且评估函数调用的结果通常是 - 虽然并非总是如此! - 一个右值表达式。

答案 4 :(得分:1)

§5.2.2/ 10(在N3225中)陈述:

  

如果结果类型是左值引用类型或对函数类型的右值引用,则函数调用是左值;如果结果类型是对象类型的右值引用,则为xvalue,否则为prvalue。