Para o código a seguir, quase a última asserção passa:
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 que esta última afirmação falha e static_cast<T>
nem sempre retorna uma T
?
c++
static-cast
Eric
fonte
fonte
T_cast i{1};
que receboinvalid initialization of non-const reference of type 'T_cast' {aka 'int (&)(int)'} from an rvalue of type '<brace-enclosed initializer list>'
, portanto, por qualquer motivo,T_cast
é umint (&)(int)
e não umint (&&)(int)
.Respostas:
Isso é codificado na definição de
static_cast
:decltype
respeita a categoria de valor de seu operando e produz uma referência lvalue para expressões lvalue.O raciocínio pode ser devido aos nomes de funções sempre serem lvalues e, portanto, um rvalue de um tipo de função não pode aparecer "em estado selvagem". Como tal, transmitir para esse tipo provavelmente faz pouco sentido.
fonte