[Moved from the gcc list] On 17 February 2011 11:03, Pascal Francq wrote: > Hi, > While compiling the following code, I got an error : > > > template<class C> class Super > { > public: > Super(void) {} > void Test(C*) {} > }; > > class A > { > public: > A(void) {} > }; > > class A1 : public A > { > public: > A1(void) : A() {} > }; > > class A2 : public A > { > public: > A2(void) : A() {} > }; > > class Super2 : public Super<A1>, public Super<A2> > { > public: > Super2(void) {} > }; > > void Test(void) > { > Super2 T; > A1* ptr; > T.Test(ptr); > } > > > The compiler gives me the following error for the Test() function: > error: request for member ‘Test’ is ambiguous > error: candidates are: void Super<C>::Test(C*) [with C = A2] > error: void Super<C>::Test(C*) [with C = A1] > But here the call refers clearly to the second method. The error still appears > if A1 and A2 do not inherit from a same root class. If I replace the code with > an explicit call it works: > T.Super<A1>::Test(ptr) > But this make the code less cleaner. > > Is this a problem related to a misunderstood concept from me, a wrong > implementation or a technical problem of g++ ? The ambiguity has nothing to do with templates, the code can be reduced to: class A1 { public: void Test(A1*) {} }; class A2 { public: void Test(A2*) {} }; class Super2 : public A1, public A2 { }; void Test(void) { Super2 T; A1* ptr; T.Test(ptr); } This is covered by 10.2 [class.member.lookup] in the C++ standard, which says that a name is ambiguous if found in more than one base class. That makes the lookup ill-formed, before overload resolution is attempted.