C++中函数返回的值是右值吗?无法使用复制/移动构造函数初始化实例
Is the value returned by a function in C++ is an rvalue? Failed to initialize an instance with copy/move constructor
我试图用函数的返回值初始化一个实例。我原以为它会调用move构造函数,但结果不是。返回值似乎被实例t直接接管了。因为函数中的t和返回值是同一个地址。编译器是否优化了这种情况?
我的环境是Mac OS X特立独行者,默认g++-std=c++11
class T1 {
public:
T1() {
printf("T1::constructorn");
t = new char[100];
}
T1(const T1 &another) {
printf("T1::copy_constructorn");
}
T1(T1 &&another) {
printf("T1::move_constructorn");
}
char *t;
};
T1 func() {
T1 t;
printf("add:%dn", static_cast<void*>(&t));
return t;
}
void rref_test() {
T1 t = func();
T1 t2 = std::move(t);
printf("add:%dn", static_cast<void*>(&t));
}
int main() {
rref_test();
return 0;
}
这取决于返回类型。如果返回类型是左值引用,那么函数调用表达式就是左值,否则就是右值。
当您编写T1 t = func();
时,func()
是一个右值。然而,这种情况可能会导致复制省略,这就是为什么您看不到任何复制构造函数或移动构造函数调用的原因。
对于T1 t2 = std::move(t);
,您应该看到对move构造函数的调用。
有些编译器具有禁用复制省略的开关,例如,对于gcc,它是-fno-elide-constructors
。
相关文章:
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- std::元组分配和复制/移动异常保证
- std::async 如何工作:为什么它会调用这么多次复制/移动?
- 在临时将成员带出时省略复制/移动
- 是否可以避免在以下代码中复制/移动构造函数的需要?
- 默认复制/移动构造函数时 GDB 中的奇怪行为
- 返回 *&object 时是否允许复制/移动省略?
- 删除复制构造函数是否也会删除默认的复制/移动运算符?
- 用于删除复制/移动分配运算符的有效签名
- 复制 elision/RVO 会导致从同一对象复制/移动吗?
- 意外缺少隐式声明的复制/移动构造函数
- 是否可以传递具有捕获的不可复制(移动)值的 lambda
- CRTP 和复制/移动赋值/构造函数继承
- C++复制/移动构造函数和赋值运算符
- 覆盖复制/移动分配超载时,我是否需要删除当前的成员数据
- 为什么编译器在有模板构造函数时生成复制/移动构造函数
- C++:使用引用和值解压缩元组,而无需复制/移动太多
- 从C++中的基类继承复制/移动构造函数作为构造函数
- 初始化 std::数组而不复制/移动元素
- 是否允许复制/移动省略使使用已删除函数的程序格式正确?