为什么这段代码试图调用复制构造函数?

时间:2012-01-24 18:14:40

标签: c++ c++11 copy-constructor placement-new move-constructor

我花了大量时间摆弄Visual Studio中的complilation错误。我已经将代码提炼到下面的小编译示例中,并在IdeOne上尝试了它并得到了相同的错误,您可以看到here

我想知道为什么下面的代码试图调用B(const B&)而不是B(B&&)

#include <iostream>

using namespace std;

class A {
public:
    A() : data(53) { }
    A(A&& dying) : data(dying.data) { dying.data = 0; }

    int data;

private:
    // not implemented, this is a noncopyable class
    A(const A&);
    A& operator=(const A&);
};

class B : public A { };

int main() {
    B binst;

    char* buf = new char[sizeof(B)];

    B* bptr = new (buf) B(std::move(binst));

    cout << bptr->data << endl;

    delete[] buf;
}

我没有明确定义任何构造函数,所以B(std::move(binst))应该调用编译器生成的B(B&&),不是吗?

当我将B更改为

class B : public A {
public:
    B() { }
    B(B&&) { }
};

编译好。这是为什么?

如果无法从基类修复这将是非常不方便的,因为我有一个模板类使用placement new和move构造函数,例如,它将需要每个不可复制的类(不是并且绝对不应该要求与我的模板类一起使用)来明确定义移动构造函数。

2 个答案:

答案 0 :(得分:16)

如果您使用的是Visual Studio 2010或2012,请注意:编译器会自动为您生成移动构造函数。那还没有实现。所以你需要自己写。

答案 1 :(得分:6)

您必须面对编译器错误。标准说B得到一个隐式声明和定义的移动构造函数;满足12.8(9)的所有条件(即B没有显式声明的复制构造函数,复制赋值等,并且不会隐式声明移动构造函数deleted)。