Ich bin in eine Situation gekommen, die ziemlich interessant ist, da der Code, an dem ich arbeite, kompiliert, obwohl ich überrascht bin, dass ich das möchte.Automatisch generierter Move Konstruktor mit nicht beweglichen Elementen
Die Situation ist dies. Ich habe eine Klasse mit gelöscht bewegen und Kopierkonstruktoren, die benutzerdefinierten Zuweisungsoperator hat:
struct A {
A() { }
A(const A&) = delete;
A(A&&) = delete;
A& operator=(const A&) { return *this; }
A& operator=(A&&) { return *this; }
};
Und ich habe eine andere Klasse mit A
als einzigem Mitglied. In dieser Klasse I definiert den Kopierkonstruktor aber ich hielt den Umzug Konstruktor als Standard und definiert den Zuweisungsoperator durch einen Aufruf der Swap-Funktion:
class B{
public:
A a;
B()
: a{}
{ }
B(const B&)
: a{}
{ }
B(B&& other) = default;
};
int main() {
B b1;
B b2(std::move(b1)); // compiles??
}
Warum wird die Standard-Bewegung Konstruktor Arbeit, wenn man bedenkt, dass es nicht einfach anrufen der Umzugs- oder Kopierkonstruktor A? Ich benutze gcc 4.8.4.
Ich habe ein paar Couts in der Kopie und Zuweisung hinzugefügt und es scheint zu bestätigen Ihre Hypothese, dass, nicht in der Lage, den Move-Konstruktor korrekt zu kompilieren, es einfach auf die Kopie zurückkehrt.Ich bin kein Experte für die Feinheiten des Standards, aber es sieht so aus, als ob sich die Standarddeklaration in einer Vorlage wie SFINAE verhält. – Triskeldeian
Ein defaulthafter Move-Konstruktor, der als gelöscht definiert ist, wird von der Überladungsauflösung ignoriert. Siehe N4527 [class.copy]/p11; auch [N3667] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3667.html) –
@ T.C. Neue Antwort klingt ungefähr richtig? – Barry