Чому `decltype (static_cast <T> (...))` не завжди є `T`?


24

Для наступного коду передається все, крім останнього твердження:

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
}

Чому це останнє твердження провалюється, а static_cast<T>не завжди повертається T?


Додаю, T_cast i{1};я отримую invalid initialization of non-const reference of type 'T_cast' {aka 'int (&)(int)'} from an rvalue of type '<brace-enclosed initializer list>', тому з будь-якої причини T_castце int (&)(int)швидше, ніж а int (&&)(int).
Кевін

Відповіді:


21

Це важко закодовано у визначенні static_cast :

[expr.static.cast] (моє наголос)

1 Результат виразу static_­cast<T>(v)- це результат перетворення виразу vу тип T. Якщо Tпосилальний тип lvalue або посилання rvalue на тип функції, результат є lvalue ; якщо Tпосилання rvalue на тип об'єкта, результатом є xvalue; в іншому випадку результат - первісне значення. Thestatic_­cast Оператор не відкине константность.

decltype поважає ціннісну категорію свого операнда і виробляє посилання на значення для виразів lvalue.

Міркування може бути пов’язане з тим, що самі назви функцій завжди є значеннями, і тому рецензія типу функції не може з'являтися "в природі". Таким чином, видання цього типу, мабуть, мало сенсу.


це питання стосується більш докладно "rvalue [s] типу функції [не] з'являються [ing]" в дикій природі ""
Ерік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.