user-declared
bedeutet entweder entweder Benutzer bereitgestellten (definiert durch den Benutzer), explizit vorbelegt (= default
) oder explizit gelöscht (= delete
) im Gegensatz zu implizit vorbelegt/gelöscht werden (wie Ihre Bewegung Konstruktor).
Also in Ihrem Fall ja der Umzug Konstruktor ist implizit gelöscht, weil die Kopie-Konstruktor explizit gelöscht ist (und damit benutzer erklärt).
In diesem speziellen Fall, wie würde gelöschte Kopie Konstruktor/Zuweisung Messstandardkonstruktor/Zuordnung bewegen?
Es würde nicht, aber der Standard macht keinen Unterschied zwischen diesem Fall und einem komplizierten.
Die kürzeste Antwort ist, dass mit einem implizit definiert move-Konstruktor mit einem explizit gelöscht Kopie-Konstruktor könnte in einigen Fällen gefährlich sein, das gleiches, wenn Sie einen benutzerdefinierten destructor und keine benutzerdefiniert Kopie-Konstruktor (siehe rule of three/five/zero). Nun können Sie argumentieren, dass ein benutzerdefinierter Destruktor den Kopierkonstruktor nicht löscht, aber dies ist einfach ein Fehler in der Sprache, der nicht entfernt werden kann, weil es viele alte (schlechte) Programme kaputt machen würde. Um Bjarne Stroustrup zu zitieren:
In einer idealen Welt, ich glaube, wir auf „keine Generation“ als Standard und bieten eine wirklich einfache Notation für sich entscheiden würde [...] „Gib mir alle üblichen Operationen.“ Eine "no default operations" -Richtlinie führt außerdem zu Kompilierungszeitfehlern (die wir leicht beheben sollten), während eine Richtlinie zum Generieren von Vorgängen standardmäßig zu Problemen führt, die erst zur Laufzeit erkannt werden.
Sie können mehr darüber in N3174=10-0164 lesen.
Beachten Sie, dass die meisten Leute die rule of three/five/zero folgen, und meiner Meinung nach sollten Sie. Durch das implizite Löschen des Standard-Move-Konstruktors "schützt" der Standard Sie vor Fehlern und sollte Sie lange Zeit davor schützen, indem Sie in einigen Fällen den Kopierkonstruktor löschten (siehe Bjarnes Beitrag).
Literaturhinweise, wenn Sie interessiert sind:
Ich denke, diese Frage praktische Bedeutung hat, weil manuelle Generation und esp. die Aufrechterhaltung solcher Standardfunktionen ist fehleranfällig, während zur gleichen Zeit die (rechtschaffene) Zunahme der Verwendung von Klassen wie std::unique_ptr
als Klassenmitglieder nicht kopierbare Klassen viel häufiger als zuvor gemacht hat.
class Foo {
public:
Foo() = default;
Foo(Foo const &) = delete;
Foo(Foo&&) = default;
};
Sie erhalten ein nicht-kopierbaren Objekt mit einem Standard-Bewegung Konstruktor, und meiner Meinung nach diesen expliziten Erklärungen sind besser als implizites: als explizit vorgegeben wird dieses Problem lösen
den Umzug Konstruktor Marking (z. B. indem der Move-Konstruktor nur als default
deklariert wird, ohne den Kopierkonstruktor zu löschen).
Nicht sicher, Ihre Frage gut zu verstehen, aber warum move ctor nicht standardmäßig? d. h. 'Foo (Foo &&) = default;' –