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

时间:2014-10-01 05:40:54

标签: c++ c++11 move-semantics rvalue

我尝试使用函数的返回值初始化一个实例。我预计它将调用移动构造函数,但结果不是。似乎返回值直接由实例t接管。因为函数中的t和返回值是相同的地址。编译器是否优化了这种情况?

我的环境是Mac OS X mavericks,默认为g ++ -std = c ++ 11

class T1 {
 public:
  T1() {
    printf("T1::constructor\n");
    t = new char[100];
  }
  T1(const T1 &another) {
    printf("T1::copy_constructor\n");
  }
  T1(T1 &&another) {
    printf("T1::move_constructor\n");
  }
  char *t;
};

T1 func() {
  T1 t;
  printf("add:%d\n", static_cast<void*>(&t));
  return t;
}

void rref_test() {
  T1 t = func();
  T1 t2 = std::move(t);
  printf("add:%d\n", static_cast<void*>(&t));
}


int main() {
  rref_test();

  return 0;
}

1 个答案:

答案 0 :(得分:3)

这取决于返回类型。如果返回类型是左值引用,则函数调用表达式是左值,否则它是右值。

当您撰写T1 t = func();时,func()是左值。但是,这种情况是copy elision的候选者,这就是为什么你没有看到任何copy-constructor或move-constructor调用的原因。

对于T1 t2 = std::move(t);,您应该看到对move-constructor的调用。

某些编译器具有禁用复制省略的开关,例如使用gcc是-fno-elide-constructors