Perché `decltype (static_cast <T> (…))` non è sempre `T`?


24

Per il codice seguente, passano tutte tranne l'ultima asserzione:

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
}

Perché quest'ultima asserzione fallisce e static_cast<T>non restituisce sempre una T?


Aggiungo T_cast i{1};che ottengo invalid initialization of non-const reference of type 'T_cast' {aka 'int (&)(int)'} from an rvalue of type '<brace-enclosed initializer list>', quindi per qualsiasi motivo T_castè un int (&)(int)piuttosto che un int (&&)(int).
Kevin,

Risposte:


21

Questo è codificato nella definizione di static_cast:

[expr.static.cast] (sottolineatura mia)

1 Il risultato dell'espressione static_­cast<T>(v)è il risultato della conversione dell'espressione vin tipo T. Se Tè un tipo di riferimento lvalue o un riferimento rvalue al tipo di funzione, il risultato è un valore lvalue ; se Tè un riferimento di valore rvalore al tipo di oggetto, il risultato è un valore x; in caso contrario, il risultato è un valore. L' static_­cast operatore non deve eliminare la costanza.

decltype rispetta la categoria di valore del suo operando e produce un riferimento lvalue per le espressioni lvalue.

Il ragionamento può essere dovuto al fatto che i nomi delle funzioni sono sempre valori, e quindi un valore di un tipo di funzione non può apparire "in the wild". In quanto tale, il casting per quel tipo probabilmente ha poco senso.


questa domanda affronta in modo più dettagliato "rvalue [s] di un tipo di funzione [not] compare [ing]" in the wild ""
Eric
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.