Tiré de la mise en œuvre du CCG, type_traits
pourquoi est-il static_cast
nécessaire ici?
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
la source
la source
Réponses:
Un type n'est pas constructible à partir d'une liste d'arguments si la déclaration de variable inventée
serait bien formé et est connu pour ne pas lever d'exceptions . Dans le cas de l'argument pluriel, ceci est équivalent (modulo noexcept destructibility, voir LWG 2116 ) à la bonne formation et au non-retour de l' expression de conversion de type
Cependant, dans le cas d'un seul argument, l'expression
T(declval<Args>())
est traitée comme une expression cast , qui peut invoquerconst_cast
etreinterpret_cast
; l'utilisation explicite destatic_cast
restaure l'équivalence du formulaire de déclaration.À titre d' exemple concret , considérons les types:
Ici, un
static_cast
deB const
àD&&
doit utiliser l'opérateur de conversion, mais une expression de transtypage peut contourner l'opérateur de conversion et ne l'est donc pas. Donc, omettre lestatic_cast
donnerait le mauvais résultat pouris_nothrow_constructible<D&&, B const>
.la source
static_cast
est nécessaire pour que l'expression soit toujours traitée commedirect initialization
au lieu de commecast expression
?noexcept
opérateur, mais c'est beaucoup plus proche.