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
?
c++
static-cast
Eric
quelle
quelle
T_cast i{1};
ich bekommeinvalid 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_cast
istint (&)(int)
eher ein als einint (&&)(int)
.Antworten:
Dies ist in der Definition von fest codiert
static_cast
: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.
quelle