https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102493
Bug ID: 102493 Summary: non-type template specialization for member pointer to field and function reports leads to unexpected conflict Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: marekr22 at wp dot pl Target Milestone: --- Here is minimum complete verifiable example (C++17): ```cpp #include <iostream> #include <string> #include <type_traits> template <auto Fp> struct field_type; template<typename R, typename T, R (T::*FP)> struct field_type<FP> { using type = R; }; template<typename R, typename T, typename...Args, R (T::*FP)(Args...)> struct field_type<FP> { using type = R; }; template<auto FP> using field_type_t = typename field_type<FP>::type; class Foo { public: int x = 0; double y = 0; std::string s; const int cx = 0; Foo() = default; void bar() { std::cout << "bar\n"; } int par(int z) { std::cout << "bar\n"; return z; } }; template<auto F, typename T> constexpr bool test = std::is_same_v<field_type_t<F>, T>; static_assert(test<&Foo::x, int>, ""); static_assert(test<&Foo::cx, const int>, ""); static_assert(test<&Foo::s, std::string>, ""); static_assert(test<&Foo::y, double>, ""); #ifndef HIDE_PROBLEM_ON_GCC_11 static_assert(test<&Foo::bar, void>, ""); static_assert(test<&Foo::par, int>, ""); #endif ``` This compile on all compilers https://godbolt.org/z/31svobz3z except for gcc 11.1 and 11.2 (gcc 10.3 works). Reported error is: ``` <source>: In substitution of 'template<auto FP> using field_type_t = typename field_type::type [with auto FP = &Foo::bar]': <source>:44:28: required from 'constexpr const bool test<&Foo::bar, void>' <source>:51:15: required from here <source>:21:7: error: ambiguous template instantiation for 'struct field_type<&Foo::bar>' 21 | using field_type_t = typename field_type<FP>::type; | ^~~~~~~~~~~~ <source>:9:8: note: candidates are: 'template<class R, class T, R T::* FP> struct field_type<FP> [with R = void(); T = Foo; R T::* FP = &Foo::bar]' 9 | struct field_type<FP> | ^~~~~~~~~~~~~~ <source>:15:8: note: 'template<class R, class T, class ... Args, R (T::* FP)(Args ...)> struct field_type<FP> [with R = void; T = Foo; Args = {}; R (T::* FP)(Args ...) = &Foo::bar]' 15 | struct field_type<FP> | ^~~~~~~~~~~~~~ <source>:21:7: error: invalid use of incomplete type 'struct field_type<&Foo::bar>' 21 | using field_type_t = typename field_type<FP>::type; | ^~~~~~~~~~~~ <source>:6:8: note: declaration of 'struct field_type<&Foo::bar>' 6 | struct field_type; | ^~~~~~~~~~ ```