Почему static_cast необходим в реализации is_nothrow_constructible g cc? - PullRequest
11 голосов
/ 07 января 2020

Взято из G CC реализации type_traits, почему static_cast здесь требуется?

template <typename _Tp, typename... _Args>
struct __is_nt_constructible_impl
    : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> {};

template <typename _Tp, typename _Arg>
struct __is_nt_constructible_impl<_Tp, _Arg>
    : public integral_constant<bool,
                               // Why is `static_cast` needed here?
                               noexcept(static_cast<_Tp>(declval<_Arg>()))> {};

1 Ответ

12 голосов
/ 07 января 2020

Тип неконвертируемый из списка аргументов, если изобретенная переменная объявление

T t(declval<Args>()...);

будет правильно сформировано и известно не бросить исключения . В случае множественного аргумента это эквивалентно (по модулю не исключая деструкции, см. LWG 2116 ) правильности и точности выражения преобразования

T(declval<Args>()...)

Однако в случае с одним аргументом выражение T(declval<Args>()) рассматривается как приведенное выражение , которое может вызывать const_cast и reinterpret_cast; явное использование static_cast восстанавливает эквивалентность формы декларации.

В качестве конкретного примера рассмотрим типы:

struct D;
struct B { operator D&&() const; };
struct D : B {};

Здесь static_cast от B const до D&& должен использоваться оператор преобразования, но выражение приведения может обойти оператор преобразования и поэтому не является исключением. Таким образом, пропуск static_cast даст неверный результат для is_nothrow_constructible<D&&, B const>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...