Por que `decltype (static_cast <T> (...))` nem sempre é `T`?


24

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?


Acrescento T_cast i{1};que recebo invalid 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é um int (&)(int)e não um int (&&)(int).
Kevin

Respostas:


21

Isso é codificado na definição de static_cast:

[expr.static.cast] (grifo meu)

1 O resultado da expressão static_­cast<T>(v)é o resultado da conversão da expressão vem tipo T. Se Tfor um tipo de referência lvalue ou uma referência rvalue ao tipo de função, o resultado será um lvalue ; se Té uma referência rvalue ao tipo de objeto, o resultado é um xvalue; caso contrário, o resultado é um pré-valor. O static_­cast operador não deve rejeitar a constância.

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.


esta pergunta aborda mais detalhadamente "os valores de um tipo de função [não] aparecem [ing]" em estado selvagem ""
Eric
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.