Beides std::forwardund std::movesind nichts als Abgüsse.
X x;
std::move(x);
Das Obige wandelt den l-Wert-Ausdruck xvom Typ X in einen r-Wert-Ausdruck vom Typ X um (genauer gesagt einen x-Wert). movekann 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::forwardkönnen Sie das Ziel bis zu einem gewissen Grad auswählen:
X x;
std::forward<Y>(x);
Wandelt den l-Wert-Ausdruck xvom 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).
forwardkann 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.