默认情况下是函数返回值常量(右值)

Is a function return-value constant by default (an rvalue)?

本文关键字:右值 常量 返回值 情况下 函数 默认      更新时间:2023-10-16

我正在学习右值引用,教程告诉我:

X foo();
X x;
x = foo();

很明显,在x和。之间交换资源指针(句柄)是可以的,而且效率更高临时的,然后让临时的析构函数析构x的原始资源。

换句话说,在特殊情况下,右边的赋值操作是右值,则需要使用复制赋值操作符这样的。

那么,这是否意味着函数的返回值在默认情况下总是常量,因此是右值?如果是:它们总是不变的,还是也有例外?

右值性和常量性不是同义词,而是有点正交。具有以下定义:

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

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

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

关于你的问题:不,不是所有的右值表达式都是常量。

那么,这是否意味着函数的返回值在默认情况下总是常量,因此是右值?如果是:它们总是不变的,还是也有例外?

。如果它们不返回引用类型(cv T&cv T&&),它们就是右值。如果返回类型是const限定的,则它们是常量。

这意味着从函数X foo()的返回值是一个右值(右值,如果你想新的标准),而不是一个常数。此外,在像x = foo()这样的表达式中,我们通常不关心临时值在赋值过程中是否发生了变化,这与move-semantics背后的思想非常相似。

§5.2.2/10 (N3225):

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

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

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

参见上一个问题,它告诉我们右值表达式既不是隐式的const类型,也不是它们所表示的对象本身不可变。

然而,它未定义的(或禁止的)—我忘了是哪一种)在某些情况下通过右值修改对象。这似乎为通过右值访问的对象提供了一种条件固有的不变性,并且函数调用的求值结果通常是—尽管并非总是如此!本;右值表达式

相关文章: