Dlaczego `decltype (static_cast <T> (…))` nie zawsze `T`?


24

W przypadku następującego kodu wszystkie twierdzenia oprócz ostatniego są przekazywane:

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
}

Dlaczego to ostatnie stwierdzenie zawodzi i static_cast<T>nie zawsze zwraca a T?


Daję T_cast i{1};, rozumiem invalid initialization of non-const reference of type 'T_cast' {aka 'int (&)(int)'} from an rvalue of type '<brace-enclosed initializer list>', więc z jakiegokolwiek powodu T_castjest int (&)(int)raczej niż int (&&)(int).
Kevin

Odpowiedzi:


21

Jest to zapisane w definicji static_cast:

[expr.static.cast] (moje wyróżnienie )

1 Wynik wyrażenia static_­cast<T>(v)jest wynikiem konwersji wyrażenia vna typ T. Jeśli Tjest to typ odwołania do wartości lub odwołanie do typu funkcji, wynikiem jest wartość ; jeśli Tjest odwołaniem do wartości typu obiektu, wynikiem jest wartość x; w przeciwnym razie wynik jest wartością. static_­cast Operator nie odrzucił constness.

decltype szanuje kategorię wartości swojego argumentu i tworzy odwołanie do wartości dla wyrażeń wartości.

Rozumowanie może wynikać z tego, że same nazwy funkcji zawsze są wartościami, dlatego wartość typu funkcji nie może pojawić się „na wolności”. Jako takie, rzutowanie na ten typ prawdopodobnie nie ma sensu.


to pytanie dotyczy bardziej szczegółowo „wartości [s] typu funkcji [nie] pojawiają się [ing]„ na wolności ””
Eric,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.