https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78939
--- Comment #11 from Jonathan Wakely <redi at gcc dot gnu.org> --- Oops, that was the previous diff, I meant to paste this (which constrains the __enable_if_has_tuple_size to only be used when _Tp has no cv-quals, so we avoid ambiguities): --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -88,24 +88,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct tuple_size; // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2313. tuple_size should always derive from integral_constant<size_t, N> // 2770. tuple_size<const T> specialization is not SFINAE compatible - template<typename _Tp, typename = void> - struct __tuple_size_cv_impl { }; - template<typename _Tp> - struct __tuple_size_cv_impl<_Tp, __void_t<decltype(tuple_size<_Tp>::value)>> - : integral_constant<size_t, tuple_size<_Tp>::value> { }; + template<typename _Tp, + typename _Up = typename remove_cv<_Tp>::type, + typename = typename enable_if<is_same<_Tp, _Up>::value>::type, + size_t = tuple_size<_Tp>::value> + using __enable_if_has_tuple_size = _Tp; - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 2313. tuple_size should always derive from integral_constant<size_t, N> template<typename _Tp> - struct tuple_size<const _Tp> : __tuple_size_cv_impl<_Tp> { }; + struct tuple_size<const __enable_if_has_tuple_size<_Tp>> + : public tuple_size<_Tp> { }; template<typename _Tp> - struct tuple_size<volatile _Tp> : __tuple_size_cv_impl<_Tp> { }; + struct tuple_size<volatile __enable_if_has_tuple_size<_Tp>> + : public tuple_size<_Tp> { }; template<typename _Tp> - struct tuple_size<const volatile _Tp> : __tuple_size_cv_impl<_Tp> { }; + struct tuple_size<const volatile __enable_if_has_tuple_size<_Tp>> + : public tuple_size<_Tp> { }; /// Gives the type of the ith element of a given tuple type. template<std::size_t __i, typename _Tp>