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.
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.
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
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With