考虑下面运行C ++ 11的代码。如果我理解正确的移动语义,则不应该调用复制构造函数。但它是。有人可以解释原因吗?
template<class D>
struct traced
{
public:
traced() = default;
traced(traced const&) { std::cout << typeid(D).name() << " copy ctor\n"; }
protected:
~traced() = default;
};
class A : public traced<A>{
public:
A(int x) : x_(x) {}
private:
int x_;
};
int main() {
// I thought the following two are equivalent. Apparently not.
aList.push_back(A(6)); // Prints out ".. copy ctor" ..
aList.emplace_back(6); // Does not print out " ... copy ctor"
}
答案 0 :(得分:5)
aList.push_back(A(6));
这构造了一个临时的A
并将其移动到容器中。调用隐式生成的A
移动构造函数,它需要从临时的基础子对象构造基础traced<A>
。但是,trace
显式声明了一个复制构造函数,因此默认情况下它没有移动构造函数,并且A
的移动构造函数仍然需要为其基类子对象执行复制
aList.emplace_back(6);
这会直接在容器中构造A
。不涉及任何形式的复制或移动。