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

Why is this code trying to call the copy constructor?

本文关键字:调用 复制 构造函数 代码 段代码 为什么      更新时间:2023-10-16

我刚刚在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&&) { }
};

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

如果不能从基类中修复这一问题,那将是非常不方便的,因为我有一个模板类,它像示例一样使用placement new和move构造函数,并且它将要求每个不可复制的类(这不是,也绝对不应该是与我的模板类一起使用的要求)都有一个显式定义的move构造函数。

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

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