https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71579
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> --- This seems to work OK: namespace std { template <class _Tp> struct __is_complete_impl { template <class _Up, size_t = sizeof(_Up)> static true_type _S_test(int); template <class _Up> static false_type _S_test(...); using type = decltype(_S_test<_Tp>(0)); }; template<typename _Tp> using __is_complete = typename __is_complete_impl<_Tp>::type; template<typename _Tp> using __is_cv_void = is_void<typename remove_cv<_Tp>::type>; template<typename _Tp> using __is_complete_or_void = __or_<__is_cv_void<_Tp>, __is_complete<_Tp>>; template<typename _Tp, bool = is_array<_Tp>::value> struct __is_aoub : false_type { }; template<typename _Tp> struct __is_aoub<_Tp, true> : __bool_constant<extent<_Tp>::value == 0> { }; template<typename _Tp> using __is_complete_or_void_or_aoub = __or_<__is_complete_or_void<_Tp>, __is_aoub<_Tp>>; } // ... template<typename _Tp, typename... _Args> struct is_constructible : public std::__is_constructible_impl<_Tp, _Args...>::type { static_assert( std::__and_<std::__is_complete_or_void_or_aoub<_Tp>, std::__is_complete_or_void_or_aoub<_Args>...>::value, "all types must be complete, void, or arrays of unknown bound"); };