Взято из GCC реализации, 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>()))> {};
c++
typetraits
libstdc++
static-cast
Жоао Пирес
источник
источник
Ответы:
Тип неконвертируем из списка аргументов, если придумано объявление переменной
было бы хорошо сформировано и, как известно, не бросало исключения . В случае множественного аргумента это эквивалентно (по модулю не исключая разрушаемости, см. LWG 2116 ) правильности и точности выражения преобразования типа
Однако в случае единственного аргумента выражение
T(declval<Args>())
обрабатывается как выражение приведения , которое может вызыватьconst_cast
иreinterpret_cast
; явное использованиеstatic_cast
восстанавливает эквивалентность декларации.В качестве конкретного примера рассмотрим типы:
Здесь a
static_cast
fromB const
toD&&
должен использовать оператор преобразования, но выражение приведения может обойти оператор преобразования и поэтому не является исключением. Таким образом, опусканиеstatic_cast
даст неправильный результат дляis_nothrow_constructible<D&&, B const>
.источник
static_cast
необходимо, чтобы выражение всегда обрабатывалось как,direct initialization
а не какcast expression
?noexcept
кроме объявления с использованием оператора, но это намного ближе.