type_traits
Dlaczego wzięto z wdrożenia GCC, dlaczego jest static_cast
tutaj potrzebny?
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
źródło
źródło
Odpowiedzi:
Typ nie jest możliwy do zbudowania z listy argumentów, jeśli wymyślona deklaracja zmiennej
byłby dobrze uformowany i wiadomo, że nie rzuca wyjątków . W przypadku liczby mnogiej jest to równoznaczne (modulo noexcept niszczyciel, patrz LWG 2116 ) z dobrze uformowanym wyrażeniem konwersji typu i bez niego
Jednak w przypadku pojedynczego argumentu wyrażenie
T(declval<Args>())
jest traktowane jako wyrażenie rzutowane , które może wywoływaćconst_cast
ireinterpret_cast
; jawne użyciestatic_cast
przywraca równoważność formularza zgłoszenia.Jako konkretny przykład rozważ typy:
Tutaj
static_cast
odB const
doD&&
musi używać operatora konwersji, ale wyrażenie rzutowania może ominąć operator konwersji, a więc nie jest to wyjątkiem. Pominięcie tegostatic_cast
dałoby zły wynikis_nothrow_constructible<D&&, B const>
.źródło
static_cast
jest to potrzebne, aby wyrażenie było zawsze traktowane jakodirect initialization
zamiastcast expression
?noexcept
operatora, ale jest o wiele bliżej.