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

发布于 2024-12-28 15:15:44 字数 1134 浏览 2 评论 0原文

我刚刚花费了大量的时间来解决 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&&) { }
};

它时,它可以正常编译。这是为什么呢?

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

I just spent an inordinate amount of time fiddling with a complilation error in Visual Studio. I have distilled the code into the small compilable example below and tried it on IdeOne and got the same error which you can see here.

I am wondering why the following code tries to call B(const B&) instead of 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;
}

I didn't explicitly define any constructors, so B(std::move(binst)) should call the compiler generated B(B&&), no?

When I change B to

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

It compiles fine. Why is this?

It will be extremely inconvenient if this can't be fixed from the base class because I have a template class which uses placement new and move constructors like the example, and it will require every class that is not copyable (which is not and definitely should not be a requirement for use with my template class) to have an explicitly defined move constructor.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泡沫很甜 2025-01-04 15:15:44

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

If you are using Visual Studio 2010 or 2012, be advised: the compiler does not automatically generate move constructors for you. That wasn't implemented. So you need to write them yourself.

如痴如狂 2025-01-04 15:15:44

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

You must be facing a compiler bug. The standard says that B gets an implicitly declared and defined move constructor; all the conditions of 12.8(9) are met (i.e. B does not have an explicitly declared copy constructor, copy-assignment, etc, and the move constructor would not implicitly be declared deleted).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文