Почему static_cast необходим в реализации gcc is_nothrow_constructible?

11

Взято из 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>()))> {};
Жоао Пирес
источник
Это несоответствие кажется странным
гонки на легкости на орбите
4
Вы должны задавать подобные вопросы в соответствующем списке рассылки libstdc ++
гонки на легкость на орбите

Ответы:

12

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

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 {};

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

ecatmur
источник
Таким образом, static_castнеобходимо, чтобы выражение всегда обрабатывалось как, direct initializationа не как cast expression?
Жоао Пирес
1
@ JoãoPires да, все верно. Это все еще не совсем то, что требуется стандартом, потому что невозможно протестировать ничего noexceptкроме объявления с использованием оператора, но это намного ближе.
Ecatmur
Спасибо за помощь! : D
Жоао Пирес