19

我只是在 Visual Studio 中花费了大量时间来处理编译错误。我已将代码提炼成下面的可编译的小示例,并在 IdeOne 上进行了尝试,并得到了您可以在此处看到的相同错误。

我想知道为什么以下代码尝试调用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&&) { }
};

它编译得很好。为什么是这样?

如果这不能从基类中修复,那将非常不方便,因为我有一个模板类,它使用像示例这样的放置 new 和移动构造函数,并且它将需要每个不可复制的类(这不是而且绝对应该不是与我的模板类一起使用的要求)具有明确定义的移动构造函数。

4

2 回答 2

17

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

于 2012-01-24T18:22:01.787 回答
6

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

于 2012-01-24T18:24:32.653 回答