https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90679
Bug ID: 90679 Summary: Template specialization with const: “ambiguous template instantiation” error Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: nikolaus+...@nikolaus-demmel.de Target Milestone: --- The below repro-example should compile (IMHO), but it fails with "ambiguous template instantiation". Same on gcc 7,8,9,trunk according to https://godbolt.org/z/69Bomq, so probably not a regression. clang compiles this just fine. See also https://stackoverflow.com/q/56333067/1813258 Specializing traits<Map<C>> and traits<Map<const C>> works fine, as does traits<first_type<C>> and traits<first_type<const C>>, so it seems to be this combination. In my real code `first_type<C>` has some additional template parameters for SFINAE. $ g++-9 -Wall -Wextra foobar.cpp foobar.cpp: In function 'int main()': foobar.cpp:36:38: error: ambiguous template instantiation for 'struct traits<Map<const Foo> >' 36 | std::cout << traits<Map<const Foo>>::N << std::endl; | ^~ foobar.cpp:24:8: note: candidates are: 'template<class C> struct traits<Map<first_type<C> > > [with C = const Foo]' 24 | struct traits<Map<first_type<C>>> { | ^~~~~~~~~~~~~~~~~~~~~~~~~~ foobar.cpp:30:8: note: 'template<class C> struct traits<Map<first_type<const C> > > [with C = Foo]' 30 | struct traits<Map<first_type<const C>>> { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ foobar.cpp:36:40: error: incomplete type 'traits<Map<const Foo> >' used in nested name specifier 36 | std::cout << traits<Map<const Foo>>::N << std::endl; | ^ $ g++-9 -v Using built-in specs. COLLECT_GCC=g++-9 COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/9.1.0/libexec/gcc/x86_64-apple-darwin16/9.1.0/lto-wrapper Target: x86_64-apple-darwin16 Configured with: ../configure --build=x86_64-apple-darwin16 --prefix=/usr/local/Cellar/gcc/9.1.0 --libdir=/usr/local/Cellar/gcc/9.1.0/lib/gcc/9 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-9 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --with-pkgversion='Homebrew GCC 9.1.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues Thread model: posix gcc version 9.1.0 (Homebrew GCC 9.1.0) $ cat foobar.cpp #include <iostream> #include <type_traits> class Foo {}; template <class T, class...> using first_type = T; template <class C> class Map {}; template <class C> struct traits {}; //#define FIX_GCC #ifdef FIX_GCC template <typename C> struct traits<Map<first_type<C, std::enable_if_t<!std::is_const_v<C>>>>> { static constexpr int N = 2; }; #else template <typename C> struct traits<Map<first_type<C>>> { static constexpr int N = 2; }; #endif template <typename C> struct traits<Map<first_type<const C>>> { static constexpr int N = 3; }; int main() { std::cout << traits<Map<Foo>>::N << std::endl; std::cout << traits<Map<const Foo>>::N << std::endl; return 0; }