为什么海湾合作委员会在实施is_nothrow_constructible时需要static_cast?
Why is static_cast needed in the gcc's implementation of is_nothrow_constructible?
取自 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>()))> {};
如果发明的变量声明,则类型可以从参数列表中构造 nothrow
T t(declval<Args>()...);
将格式良好,并且已知不会引发异常。在复数参数的情况下,这等价于类型转换表达式的良好格式和 nothrow (模 noexcept 可破坏性,参见 LWG 2116(
T(declval<Args>()...)
然而,在单参数的情况下,表达式T(declval<Args>())
被视为一个强制转换表达式,它可以调用const_cast
和reinterpret_cast
;显式使用static_cast
恢复了声明形式的等价性。
作为一个具体示例,请考虑以下类型:
struct D;
struct B { operator D&&() const; };
struct D : B {};
在这里,从B const
到D&&
的static_cast
必须使用转换运算符,但强制转换表达式可以绕过转换运算符,因此除外。因此,省略static_cast
会给is_nothrow_constructible<D&&, B const>
带来错误的结果。