为什么这段代码试图调用复制构造函数?
我刚刚花费了大量的时间来解决 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您使用的是 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.
您一定遇到了编译器错误。标准规定
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 declareddeleted
).