我尝试使用函数的返回值初始化一个实例。我预计它将调用移动构造函数,但结果不是。似乎返回值直接由实例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;
}
答案 0 :(得分:3)
这取决于返回类型。如果返回类型是左值引用,则函数调用表达式是左值,否则它是右值。
当您撰写T1 t = func();
时,func()
是左值。但是,这种情况是copy elision的候选者,这就是为什么你没有看到任何copy-constructor或move-constructor调用的原因。
对于T1 t2 = std::move(t);
,您应该看到对move-constructor的调用。
某些编译器具有禁用复制省略的开关,例如使用gcc是-fno-elide-constructors
。