Warum ist `decltype (static_cast <T> (…))` nicht immer` T`?


24

Für den folgenden Code werden alle bis auf die letzte Zusicherung bestanden:

template<typename T>
constexpr void assert_static_cast_identity() {
    using T_cast = decltype(static_cast<T>(std::declval<T>()));
    static_assert(std::is_same_v<T_cast, T>);
}

int main() {
    assert_static_cast_identity<int>();
    assert_static_cast_identity<int&>();
    assert_static_cast_identity<int&&>();
    // assert_static_cast_identity<int(int)>(); // illegal cast
    assert_static_cast_identity<int (&)(int)>();
    assert_static_cast_identity<int (&&)(int)>(); // static assert fails
}

Warum schlägt diese letzte Behauptung fehl und gibt static_cast<T>nicht immer ein zurück T?


Ich füge hinzu, T_cast i{1};ich bekomme invalid initialization of non-const reference of type 'T_cast' {aka 'int (&)(int)'} from an rvalue of type '<brace-enclosed initializer list>', also aus welchem ​​Grund auch immer, T_castist int (&)(int)eher ein als ein int (&&)(int).
Kevin

Antworten:


21

Dies ist in der Definition von fest codiert static_cast :

[expr.static.cast] (Hervorhebung von mir)

1 Das Ergebnis des Ausdrucks static_­cast<T>(v)ist das Ergebnis der Konvertierung des Ausdrucks vin Typ T. Wenn Tes sich um einen l-Wert-Referenztyp oder eine r-Wert-Referenz zum Funktionstyp handelt, ist das Ergebnis ein l-Wert . Wenn Tes sich um eine r-Wert-Referenz auf den Objekttyp handelt, ist das Ergebnis ein x-Wert. Andernfalls ist das Ergebnis ein Wert. Der static_­cast Betreiber darf die Konstanz nicht wegwerfen.

decltype respektiert die Wertekategorie seines Operanden und erzeugt eine l-Wert-Referenz für l-Wert-Ausdrücke.

Die Argumentation kann darauf zurückzuführen sein, dass Funktionsnamen selbst immer l-Werte sind und daher ein r-Wert eines Funktionstyps nicht "in the wild" erscheinen kann. Daher macht das Casting auf diesen Typ wahrscheinlich wenig Sinn.


Diese Frage befasst sich ausführlicher mit "rWerten [s] eines Funktionstyps [nicht], die in freier Wildbahn erscheinen"
Eric
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.