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ónv
al tipoT
SiT
es un tipo de referencia lvalue o una referencia rvalue al tipo de función, el resultado es un lvalue ; siT
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 operadorstatic_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.