Warum hat std :: forward zwei Überladungen?
Gegeben die folgenden Referenzkollapsregeln
T& &
->T&
T&& &
->T&
T& &&
->T&
T&& &&
->T&&
Die dritte und vierte Regel implizieren, dassT(ref qualifer) &&
ist die Identitätstransformation, d. h.T&
bleibt beiT&
undT&&
bleibt beiT&&
. Warum haben wir zwei Überladungen fürstd::forward
? Konnte die folgende Definition nicht allen Zwecken dienen?
template <typename T, typename = std::enable_if_t<!std::is_const<T>::value>>
T&& forward(const typename std::remove_reference<T>::type& val) {
return static_cast<T&&>(const_cast<T&&>(val));
}
Hier ist der einzige Zweck derconst std::remove_reference<T>&
dient dazu, keine Kopien zu machen. Und dieenable_if
stellt sicher, dass die Funktion nur für Nicht-Konstanten-Werte aufgerufen wird. Ich bin mir nicht ganz sicher, ob dasconst_cast
wird benötigt, da nicht die Referenz selbst const ist.
Schon seitforward
wird immer mit expliziten Template-Parametern aufgerufen. Es gibt zwei Fälle, die wir berücksichtigen müssen:
forward<Type&>(val)
Hier die Art vonT
imforward
wird seinT&
und daher ist der Rückgabetyp die Identitätsumwandlung nachT&
forward<Type&&>(val)
Hier die Art vonT
imforward
wird seinT&&
und daher ist der Rückgabetyp die Identitätsumwandlung nachT&&
So warum brauchen wir dann zwei Überladungen wie in @ beschriebhttp: //en.cppreference.com/w/cpp/utility/forwar?
Hinwei: Ich bin nicht sicher, obstd::forward
wird immer mit @ verwendconst
Arten, aber ich deaktivierteforward
in diesem Fall, weil ich es noch nie so gebraucht gesehen habe. Auch in diesem Fall ist die Bewegungssemantik nicht wirklich sinnvoll.