c++函数返回右值,但可以为其赋一个新值
C++ function returns a rvalue, but that can be assigned a new value?
代码如下:
#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++编译器给出如下错误:
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&)’
它说我不能传递右值作为非const引用的参数,但我困惑的是为什么我可以给这个右值赋值,正如代码所示。
将右值rtByValue()
传递给期望左值引用的函数不起作用,因为这将要求从右值初始化左值引用参数。§8.5.3/5描述了如何初始化左值引用& &;我就不完整引用了,它说的是左值引用可以初始化
- 从另一个左值引用
- 或可以转换为中间类型 的左值引用的内容。
- 或来自右值,但前提是我们初始化的左值引用是const-reference
由于需要初始化的实参不是const-reference,因此以上这些都不适用。
另一方面,rtByValue() = aa;
。,赋值给临时对象是可能的,因为:
(§3.10/5)对象的左值是修改对象所必需的,但是类类型的右值在某些情况下也可以用来修改其引用对象。[示例:为对象调用的成员函数(9.3)可以修改对象。]- end示例]
因此,这只适用于A
是类类型,并且(隐式定义的)赋值操作符是成员函数。(详情请参阅相关问题)
(因此,如果rtByValue()
返回,例如,int
,那么赋值将不起作用。)
因为您可以(但不应该!)重写operator=,以便在右值上调用它是有意义的。考虑下面的代码:
#include<iostream>
using namespace std;
class foo;
foo* gotAssigned = NULL;
int assignedto = -1;
class foo {
public:
foo(int v) : val(v) {}
foo& operator=(int v) {
assignedto=v;
gotAssigned = this;
val = v;
return *this;
}
int val;
};
foo theFoo(2);
foo returnTheFooByValue() {
return theFoo;
}
main() {
returnTheFooByValue()=5;
cout << "[" << assignedto << "] " << theFoo.val << " versus " << gotAssigned->val << endl;
}
现在让我们用几种方法编译它:
$ g++ -O0 -o rveq rveq.cc && ./rveq
[5] 2 versus 5
$ g++ -O1 -o rveq rveq.cc && ./rveq
[5] 2 versus 2
$ g++ -O4 -o rveq rveq.cc && ./rveq
[5] 2 versus -1218482176
我不能保证你会看到同样的结果。
正如您所看到的,赋值发生了,但是任何使用被赋值对象的尝试都会导致特定于实现的行为。
顺便说一下,这个只适用于用户定义的类型。这段代码:int v(){
return 2;
}
main(){
v()=4;
}
不编译。
@ddriver输出数字7,如我所料。
#include <iostream>
using namespace std;
class A {
public:
int i;
A() {i = 0x07;}
};
A rtByValue() {
return A();
}
void passByRef(A &aRef) {
cout << aRef.i;
}
int main() {
passByRef(rtByValue());
return 0;
}
相关文章:
- C++使用另一个数组和新值初始化数组
- 变体 - 分配新值时是否清理旧值?
- C++:我可以在线程仍在运行时为线程提供新值,还是必须先结束它?
- C++类析构函数使用新值而不是实际值
- 写入新值是构成前增量表达式"value computation"的一部分,还是"side effect"?
- 我们是否可以保证任何原子写入都会立即将原子变量的新值存储在主存储器中?
- C++:初始化(新)一个不同初始大小的向量数组
- C++ - 读取进程内存到缓冲区,写入进程内存(同一缓冲区上的新值)将缓冲区恢复为旧值
- 新的一个一维阵列,非常大,例如60000*60000
- 将新值添加到链表中
- 如何在while循环之外分配一个新值
- 在为其分配一个新值之前,应将`nullptr`分配给`sTD :: simelod_ptr`
- 无限数组C++在一个表达式中使用两个新值调整数组大小
- 为什么reverse_iterator无法使用forward Itererator分配一个新值
- 在数组的元素中插入一个新值,然后移动其余元素
- 给QStringListModel的私有QStringList赋值一个新的QStringList
- c++函数返回右值,但可以为其赋一个新值
- 为什么可以给引用赋一个新值,以及如何使引用引用其他东西
- C++将两个变量中较大的一个设置为新值
- 将特定位置的位收集为一个新值