Sollte ein Verschiebungskonstruktor eine konstante oder eine nicht konstante Wertreferenz verwenden?

An mehreren Stellen habe ich die empfohlenen Signaturen von Copy & Move-Konstruktoren gesehen, die wie folgt lauten:

struct T
{
    T();
    T(const T& other);
    T(T&& other);
};

Wobei der Kopierkonstruktor eine konstante Referenz und der Verschiebungskonstruktor eine nicht konstante Referenz verwendet.

So weit ich das sehe, kann ich die Verschiebungssemantik nicht nutzen, wenn ich const-Objekte von einer Funktion zurückgebe, wie im folgenden Fall:

T generate_t()
{
    const T t;
    return t;
}

Testen Sie dies mit VC11 Beta,TDer Kopierkonstruktor von wird aufgerufen und nicht der Verschiebungskonstruktor. Sogar mitreturn std::move(t); Der Kopierkonstruktor wird weiterhin aufgerufen.

Ich kann sehen, wie das Sinn macht, seitdemt ist const, sollte also nicht bindenT&&. Verwendenconst T&& in der Bewegung Konstruktor Signatur funktioniert gut und macht Sinn, aber dann haben Sie das Problem, dass weilother Ist const, können Sie die Elemente nicht auf Null setzen, wenn sie auf Null gesetzt werden müssen. Dies funktioniert nur, wenn alle Elemente Skalare sind oder Verschiebungskonstruktoren mit der richtigen Signatur haben.

Es sieht so aus, als ob nur so sichergestellt werden kann, dass der move-Konstruktor im allgemeinen Fall aufgerufen wirdt non-const an erster stelle, aber das mache ich nicht gerne - consting things ist eine gute form und ich würde nicht erwarten, dass der client vonT zu wissen, dass sie gegen diese Form vorgehen mussten, um die Leistung zu steigern.

Ich schätze, meine Frage ist zweifach. Soll ein Verschiebungskonstruktor zunächst eine konstante oder eine nicht konstante Wertreferenz verwenden? Und zweitens: Habe ich Recht mit dieser Argumentation? Dass ich aufhören soll, Dinge zurückzugeben, die const sind?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage