c++ static-cast

c++ - ¿Por qué `decltype(static_cast<T>(...))` no siempre es `T`?



static-cast (1)

Para el siguiente código, todos, excepto la última aserción, pasan:

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 }

¿Por qué esta última afirmación falla y static_cast<T> no siempre devuelve una T ?


Esto está codificado en la definición de static_cast :

[expr.static.cast] (énfasis mío)

1 El resultado de la expresión static_cast<T>(v) es el resultado de convertir la expresión v al tipo T Si T es un tipo de referencia lvalue o una referencia rvalue al tipo de función, el resultado es un lvalue ; si T es una referencia de valor de r al tipo de objeto, el resultado es un valor de x; de lo contrario, el resultado es un prvalue. El operador static_cast no debe desechar la constidad.

decltype respeta la categoría de valor de su operando y produce una referencia lvalue para expresiones lvalue.

El razonamiento puede deberse a que los nombres de las funciones siempre son valores, por lo que un valor de un tipo de función no puede aparecer "en la naturaleza". Como tal, lanzar a ese tipo probablemente tenga poco sentido.