https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79960
Bug ID: 79960 Summary: [5/6/7 Regression] Class template partial specializations for const volatile types don't match Product: gcc Version: 7.0.1 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- using size_t = decltype(sizeof(0)); template<typename T> struct tuple_size; template<typename T, size_t U = tuple_size<T>::value> using __has_tuple_size = T; template<typename T> struct tuple_size<const __has_tuple_size<T>> { static constexpr size_t value = tuple_size<T>::value; }; template<typename T> struct tuple_size<volatile __has_tuple_size<T>> { static constexpr size_t value = tuple_size<T>::value; }; template<typename T> struct tuple_size<const volatile __has_tuple_size<T>> { static constexpr size_t value = tuple_size<T>::value; }; template<typename... T> struct tuple { }; template<typename... T> struct tuple_size<tuple<T...>> { static constexpr size_t value = sizeof...(T); }; static_assert( tuple_size<const tuple<>>::value == 0, "" ); // OK static_assert( tuple_size<volatile tuple<>>::value == 0, "" ); // OK static_assert( tuple_size<const volatile tuple<>>::value == 0, "" ); // FAIL GCC trunk fails to match the specialization: cv.cc:27:50: error: ambiguous template instantiation for ‘struct tuple_size<const volatile tuple<> >’ static_assert( tuple_size<const volatile tuple<>>::value == 0, "" ); // FAIL ^~ cv.cc:8:29: note: candidates are: template<class T> struct tuple_size<__has_tuple_size<T> > [with T = volatile tuple<>] template<typename T> struct tuple_size<const __has_tuple_size<T>> { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cv.cc:12:29: note: template<class T> struct tuple_size<__has_tuple_size<T> > [with T = const tuple<>] template<typename T> struct tuple_size<volatile __has_tuple_size<T>> { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cv.cc:16:29: note: template<class T> struct tuple_size<__has_tuple_size<T> > [with T = tuple<>] template<typename T> struct tuple_size<const volatile __has_tuple_size<T>> { ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cv.cc:27:52: error: incomplete type ‘tuple_size<const volatile tuple<> >’ used in nested name specifier static_assert( tuple_size<const volatile tuple<>>::value == 0, "" ); // FAIL ^~~~~