【发布时间】:2014-06-11 20:41:08
【问题描述】:
所以,代码优先:
#include <iostream>
#include <utility>
struct X{
int i;
void transform(){}
X() :i(0){std::cout<<"default\n";}
X(const X& src): i(src.i){std::cout<<"copy\n";}
X(X&& msrc) :i(msrc.i){msrc.i=0;std::cout<<"move\n";}
};
X getTransform(const X& src){
X tx(src);
tx.transform();
return tx;
}
int main(){
X x1;// default
X x2(x1); // copy
X x3{std::move(X{})}; // default then move
X x41(getTransform(x2)); // copy in function ,then what?
X x42(std::move(getTransform(x2))); // copy in funciton, then move
X x51( (X()) );//default, then move? or copy?
// extra() for the most vexing problem
X x52(std::move(X())); //default then move
std::cout<<&x41<<"\t"<<&x51<<std::endl;
}
然后从 cygwin + gcc 4.8.2 输出,开启 C++11 功能:
default
copy
default
move
copy
copy
move
default
default
move
0x22aa70 0x22aa50
我不太明白的是 x41 和 x51 的线。对于 x41,函数调用返回的临时值应该调用移动构造函数还是副本? x51 也有同样的问题。
第二个问题是,通过查看输出,x41 和 x51 的构造没有调用任何定义的构造函数,但是对象显然是在内存中创建的。这怎么可能?
【问题讨论】:
-
一个未命名的对象自然比
const&匹配&&更好。否则移动语义将不起作用。尽管如此,如果它是从函数返回并直接用于初始化相同类型的对象,则该移动将被省略。 -
有趣。看起来 g++ 版本必须更多地处理他们的移动语义:省略副本比仅仅移动更好。
标签: c++ c++11 move-constructor temporary-objects