Aus der GCC-Implementierung entnommen, type_traits
warum hier static_cast
benötigt wird?
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
João Pires
quelle
quelle
Antworten:
Ein Typ ist nothrow konstruierbar aus einer Argumentliste , wenn die Variable erfundene Erklärung
wäre wohlgeformt und ist dafür bekannt, keine Ausnahmen zu werfen . Im Fall des Pluralarguments ist dies äquivalent (Modulo noexcept destructibility, siehe LWG 2116 ) zu der Wohlgeformtheit und Nichtform des Typkonvertierungsausdrucks
Im Fall
T(declval<Args>())
eines einzelnen Arguments wird der Ausdruck jedoch als Cast-Ausdruck behandelt , derconst_cast
undreinterpret_cast
aufrufen kann . Durch die explizite Verwendung von wirdstatic_cast
die Äquivalenz zum Deklarationsformular wiederhergestellt.Betrachten Sie als konkretes Beispiel die Typen:
Hier muss ein
static_cast
vonB const
bisD&&
den Konvertierungsoperator verwenden, aber ein Cast-Ausdruck kann den Konvertierungsoperator umgehen und ist daher keine Ausnahme. Wenn Sie also das weglassenstatic_cast
, erhalten Sie das falsche Ergebnisis_nothrow_constructible<D&&, B const>
.quelle
static_cast
wird also benötigt, damit der Ausdruck immer alsdirect initialization
statt als behandelt wirdcast expression
?noexcept
Operator zu testen , aber es ist viel näher.