https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89231
Bug ID: 89231 Summary: Ambiguous template instantiation for variadic nested class Product: gcc Version: 8.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: andreas.stoeckel at googlemail dot com Target Milestone: --- The following program causes an "ambiguous template instantiation" error in G++ g++ (GCC) 8.2.1 20181215, although one of the class specialisations should be preferred. ---- template<typename... Ps> struct A { template <int... Ns> struct Collect {}; template <int C, int I = 0, typename S = Collect<>> struct Seq; template <int C, int I, int... N> struct Seq<C, I, Collect<N...>> : Seq<C - 1, I + 1, Collect<N..., I>> {}; template <int I, int... N> struct Seq<0, I, Collect<N...>> : Collect<N...> {}; }; int main() { A<>::Seq<4> test; } --- Error: test.cpp: In instantiation of ‘struct A<>::Seq<1, 3, A<>::Collect<0, 1, 2> >’: test.cpp:10:9: recursively required from ‘struct A<>::Seq<3, 1, A<>::Collect<0> >’ test.cpp:10:9: required from ‘struct A<>::Seq<4>’ test.cpp:17:14: required from here test.cpp:10:9: error: ambiguous template instantiation for ‘struct A<>::Seq<0, 4, A<>::Collect<0, 1, 2, 3> >’ struct Seq<C, I, Collect<N...>> : Seq<C - 1, I + 1, Collect<N..., I>> {}; ^~~~~~~~~~~~~~~~~~~~~~~~ test.cpp:10:9: note: candidates are: ‘template<class ... Ps> template<int C, int I, int ...N> struct A<Ps>::Seq<C, I, A<Ps>::Collect<N ...> > [with int C = 0; int I = 4; int ...N = {0, 1, 2, 3}; Ps = {}]’ test.cpp:13:9: note: ‘template<class ... Ps> template<int I, int ...N> struct A<Ps>::Seq<0, I, A<Ps>::Collect<N ...> > [with int I = 4; int ...N = {0, 1, 2, 3}; Ps = {}]’ struct Seq<0, I, Collect<N...>> : Collect<N...> {}; ^~~~~~~~~~~~~~~~~~~~~~~~ test.cpp:10:9: error: invalid use of incomplete type ‘struct A<>::Seq<0, 4, A<>::Collect<0, 1, 2, 3> >’ struct Seq<C, I, Collect<N...>> : Seq<C - 1, I + 1, Collect<N..., I>> {}; ^~~~~~~~~~~~~~~~~~~~~~~~ test.cpp:7:9: note: declaration of ‘struct A<>::Seq<0, 4, A<>::Collect<0, 1, 2, 3> >’ struct Seq; --- Note: this code compiles fine with clang++. It also compiles fine as long as "struct A" is not a template.