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.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage