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

Set*_*gie 18 c++ copy-constructor placement-new move-constructor c++11

我花了大量的时间来摆弄Visual Studio中的complilation错误.我已经将代码提炼到下面的小编译示例中,并在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;
}
Run Code Online (Sandbox Code Playgroud)

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

当我B改为

class B : public A {
public:
    B() { }
    B(B&&) { }
};
Run Code Online (Sandbox Code Playgroud)

它汇编很好.为什么是这样?

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

Nic*_*las 17

如果您在使用Visual Studio 2010或2012年,被告知:编译器不会自动生成move构造函数为您服务.那没有实现.所以你需要自己写.

  • @Seth Carnegie:VC11也不会生成自动移动构造函数... http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx"Rvalue references v3.0添加新规则在某些条件下自动生成移动构造函数和移动赋值运算符.这将不会在VC11中实现,VC11将继续遵循VC10从不自动生成移动构造函数/移动赋值运算符的行为." (4认同)
  • 应当注意,何时将移动构造函数隐式定义为默认值的细节在标准化过程快要结束时发生了变化,而vc2010在此之前已经发生了变化。另外,vc2010不支持`= delete`,这使得很难谈论move构造函数的一致性:) (2认同)

Ker*_* SB 6

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

  • 我想这就是我使用VS编写的,这是一个在标准之间编写的编译器.谢谢. (2认同)