Beides std::forward
und std::move
sind nichts als Abgüsse.
X x;
std::move(x);
Das Obige wandelt den l-Wert-Ausdruck x
vom Typ X in einen r-Wert-Ausdruck vom Typ X um (genauer gesagt einen x-Wert). move
kann auch einen rwert akzeptieren:
std::move(make_X());
und in diesem Fall handelt es sich um eine Identitätsfunktion: Nimmt einen r-Wert vom Typ X und gibt einen r-Wert vom Typ X zurück.
Mit std::forward
können Sie das Ziel bis zu einem gewissen Grad auswählen:
X x;
std::forward<Y>(x);
Wandelt den l-Wert-Ausdruck x
vom Typ X in einen Ausdruck vom Typ Y um. Es gibt Einschränkungen, was Y sein kann.
Y kann eine zugängliche Basis von X sein oder ein Verweis auf eine Basis von X. Y kann X sein oder ein Verweis auf X. Man kann Lebenslauf-Qualifizierer nicht mit wegwerfen forward
, aber man kann Lebenslauf-Qualifizierer hinzufügen. Y kann kein Typ sein, der lediglich von X konvertierbar ist, außer über eine zugängliche Basiskonvertierung.
Wenn Y eine lWertreferenz ist, ist das Ergebnis ein lWertausdruck. Wenn Y keine l-Wert-Referenz ist, ist das Ergebnis ein r-Wert-Ausdruck (genauer gesagt x-Wert).
forward
kann ein rvalue-Argument nur annehmen, wenn Y keine lvalue-Referenz ist. Das heißt, Sie können keinen Wert in einen Wert umwandeln. Dies ist aus Sicherheitsgründen so, da dies häufig zu baumelnden Referenzen führt. Aber es ist in Ordnung und erlaubt, einen Wert in einen Wert umzuwandeln.
Wenn Sie versuchen, Y für etwas anzugeben, das nicht zulässig ist, wird der Fehler zur Kompilierungszeit und nicht zur Laufzeit abgefangen.