Perché static_cast è necessario per l'implementazione di is_nothrow_constructible da parte di gcc?


11

Tratto dall'implementazione GCC del type_traitsperché è static_castnecessario qui?

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

Questa incoerenza sembra strana
gare di leggerezza in orbita il

4
Dovresti porre domande come questa nella relativa mailing list libstdc ++
Lightness Races in Orbit

Risposte:


12

Un tipo non è costruibile da un elenco di argomenti se la dichiarazione della variabile inventata

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

sarebbe ben formato ed è noto per non generare eccezioni . Nel caso dell'argomento plurale questo è equivalente (modulo noexcept destructibility, vedi LWG 2116 ) alla ben formata e nothrow dell'espressione di conversione del tipo

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

Tuttavia, nel caso del singolo argomento, l'espressione T(declval<Args>())viene trattata come espressione cast , che può invocare const_castereinterpret_cast ; l'uso esplicito di static_castripristina l'equivalenza al modulo di dichiarazione.

A titolo di esempio concreto , considerare i tipi:

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

Qui un static_castda B consta D&&deve usare l'operatore di conversione, ma un'espressione di cast può bypassare l'operatore di conversione e quindi non è escluso. Quindi omettere il static_castdarebbe il risultato sbagliato per is_nothrow_constructible<D&&, B const>.


Quindi static_castè necessario affinché l'espressione sia sempre trattata come direct initializationanziché come cast expression?
João Pires

1
@ JoãoPires sì, esatto. Non è ancora esattamente ciò che è richiesto dalla norma perché non è possibile testare nessuna eccezione di una dichiarazione utilizzando l' noexceptoperatore, ma è molto più vicino.
ecatmur

grazie per l'aiuto! : D
João Pires
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.