C++中函数返回的值是右值吗?无法使用复制/移动构造函数初始化实例

Is the value returned by a function in C++ is an rvalue? Failed to initialize an instance with copy/move constructor

本文关键字:复制 移动 实例 初始化 构造函数 返回 函数 C++      更新时间:2023-10-16

我试图用函数的返回值初始化一个实例。我原以为它会调用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