Ответ 1
Если вы используете Visual Studio 2010 или 2012, имейте в виду: компилятор автоматически не создает для вас конструкторы перемещения. Это не было реализовано. Поэтому вам нужно написать их самостоятельно.
Я просто потратил чрезмерное количество времени, затрачиваемое на ошибку компиляции в 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&&)
, no?
Когда я меняю B
на
class B : public A {
public:
B() { }
B(B&&) { }
};
Он компилируется отлично. Почему это?
Это будет крайне неудобно, если это невозможно исправить из базового класса, потому что у меня есть класс шаблонов, который использует размещение new и перемещает конструкторы, подобные этому примеру, и для этого потребуется каждый класс, который не копируется (что не является и определенно не должно быть требованием для использования с моим классом шаблона), чтобы иметь явно определенный конструктор перемещения.
Если вы используете Visual Studio 2010 или 2012, имейте в виду: компилятор автоматически не создает для вас конструкторы перемещения. Это не было реализовано. Поэтому вам нужно написать их самостоятельно.
Вы должны столкнуться с ошибкой компилятора. В стандарте указано, что B
получает неявно объявленный и определенный конструктор перемещения; все условия 12.8 (9) выполнены (т.е. B
не имеет явно объявленного конструктора копирования, копирования и т.д., и конструктор перемещения не будет объявлен неявно deleted
).