问题描述
代码如下:
#include <iostream>
using namespace std;
class A {
};
A rtByValue() {
return A();
}
void passByRef(A &aRef) {
// do nothing
}
int main() {
A aa;
rtByValue() = aa; // compile without errors
passByRef(rtByValue()); // compile with error
return 0;
}
g++ 编译器给出以下错误:
The g++ compiler gives the following error:
d.cpp: In function ‘int main()’:
d.cpp:19:23: error: invalid initialization of non-const reference of type ‘A&’ from an rvalue of type ‘A’
d.cpp:12:6: error: in passing argument 1 of ‘void passByRef(A&)’
它说我不能将右值作为非常量引用的参数传递,但我感到困惑的是为什么我可以分配给这个右值,正如代码所示.
It says that I can't pass an rvalue as an argument of a non-const reference, but what I'm confused about is why I can assign to this rvalue, just as the code shows.
推荐答案
将右值 rtByValue()
传递给需要左值引用的函数不起作用,因为这将需要左值引用参数从右值初始化.§8.5.3/5 描述了如何初始化左值引用——我不会完整引用它,但它基本上是说可以初始化左值引用
Passing the rvalue rtByValue()
to a function that expects an lvalue reference doesn't work because this would require the lvalue reference argument to be initialized from an rvalue. §8.5.3/5 describes how lvalue references can be initialized – I won't quote it in full, but it basically says that an lvalue reference can be initialized
- 来自另一个左值引用
- 或者可以转换为中间类型的左值引用的东西
- 或来自右值,但前提是我们初始化的左值引用是常量引用
由于我们需要初始化的参数不是常量引用,所以这些都不适用.
Since the argument we need to initialize is not a const-reference, none of this applies.
另一方面,
rtByValue() = aa;
即分配给临时对象是可能的,因为:
i.e., assigning to a temporary object, is possible because of:
(§3.10/5) 对象的左值对于修改对象是必要的,除了在某些情况下也可以使用类类型的右值来修改其所指对象.[ 示例:为对象调用的成员函数(9.3)可以修改该对象.— 结束示例 ]
所以这只是因为 A
是类类型的,并且(隐式定义的)赋值运算符是一个成员函数.(请参阅此相关问题了解更多详情.)
So this works only because A
is of class-type, and the (implicitly defined) assignment operator is a member function. (See this related question for further details.)
(因此,如果 rtByValue()
返回,例如,int
,则赋值将不起作用.)
(So, if rtByValue()
were to return, for example, an int
, then the assignment wouldn't work.)
这篇关于C++ 函数返回一个右值,但可以为其分配一个新值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!