https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96710
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #0) > Our definitions of is_scalar depends on is_arithmetic, so > is_scalar<__int128> is false, and therefore is_object<__int128> is false. > This is clearly nonsense. Hmm, what I wrote is nonsense. Our is_object does not depend on is_scalar: /// is_object template<typename _Tp> struct is_object : public __not_<__or_<is_function<_Tp>, is_reference<_Tp>, is_void<_Tp>>>::type { }; So is_object<__int128> is always true. But is_scalar<__int128> still depends on __STRICT_ANSI__ which seems wrong. It's not a compound type, so it's scalar. Currently we define is_scalar as: template<typename _Tp> struct is_scalar : public __or_<is_arithmetic<_Tp>, is_enum<_Tp>, is_pointer<_Tp>, is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type { }; I think a better definition would be: template<typename _Tp> struct is_scalar : public __and_<is_object<_Tp>, __not_<is_array<_Tp>>, __not_<is_class<_Tp>>, __not_<is_union<_Tp>>> { }; Which could be optimized using partial specializations for the array cases: template<typename _Tp> struct is_scalar : public __and_<is_object<_Tp>, __not_<is_class<_Tp>>, __not_<is_union<_Tp>>> { }; template<typename _Tp> struct is_scalar<_Tp[]> : public false_type { }; template<typename _Tp, size_t _Num> struct is_scalar<_Tp[_Num]> : public false_type { };