默认情况下是函数返回值常量(右值)
Is a function return-value constant by default (an rvalue)?
我正在学习右值引用,教程告诉我:
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
类型,也不是它们所表示的对象本身不可变。
然而,它是未定义的(或禁止的)—我忘了是哪一种)在某些情况下通过右值修改对象。这似乎为通过右值访问的对象提供了一种条件固有的不变性,并且函数调用的求值结果通常是—尽管并非总是如此!本;右值表达式
- 从 BubbleSort* 类型的右值初始化 'AssortedSorter&' 类型的非常量引用无效"
- 无法将类型"T&"的非常量左值引用绑定到类型"T"的右值 t++ std::atomic<T>
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- C++11 右值引用与常量引用
- 为什么我总是收到此错误:从类型为"农场动物"的右值初始化类型的非常量引用无效|
- 为什么右值不能绑定到非常量左值引用,除了写入临时无效的事实?
- 如果可能的话,C++总是更喜欢右值引用转换运算符而不是常量左值引用吗?
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 给定一个右值,为什么移动ctor比常量复制ctor更匹配
- 为什么在这种情况下调用非常量右值移动构造函数?
- 右值引用可以作为常量引用传递吗?
- 出于什么原因,有必要将常量左值引用绑定到右值?
- 为什么可以通过常量左值引用传递右值?
- 为什么可以将左值传递到采用常量引用右值的构造函数中?
- 为什么作为返回类型的右值引用不能初始化非常量引用?
- 为什么静态常量字符 * const 变量在为左值时可绑定到右值引用参数
- 无法将类型为"类名 &"的非常量左值引用绑定到类型为"类名"的右值
- 如果常量引用延长了此右值的寿命,则此右值驻留在何处?
- 可修改的右值和常量右值有什么区别?
- 为什么右值/常量引用有内存地址和大小