>Number: 8875 >Category: c++ >Synopsis: Ambiguities in mixed template hierarchies >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: rejects-legal >Submitter-Id: net >Arrival-Date: Sun Dec 08 10:56:00 PST 2002 >Closed-Date: >Last-Modified: >Originator: Stefan Große Pawig >Release: gcc (GCC) 3.2.1 (also with 3.2) >Organization: >Environment: Linux rigel 2.4.18 #5 Thu Aug 1 22:19:10 CEST 2002 i686 unknown >Description: The following code snippet (see below) exercises a base class template with concrete and pure virtual methods as well as general and specialized derived templates, which provide implementations for the pure virtual methods. Spezializations are provided for void* as well as for pointers in general, which builds on the void* spezialization via private inheritance. The problem occurs when one of the concrete methods of the base class is called on an instantiation of the derived template for pointers (Derviced in the sample code): the compiler complains that the concrete member is ambiguous (line 37). Using explicit qualification works for Base::doThat() but fails for Base::doThat() as expected (line 39), so why does the compiler regard the unqualified call as ambiguous? Am I missing something here? Or is this an effect of the "Two stage lookup in templates is not implemented." as stated on the "GCC Bugs" page? >How-To-Repeat: pawig@rigel:~/src > cat ctest1.cc // Base class template template class Base { public: virtual T doThis() const = 0; bool doThat() const { return doThis() == T(); } }; // General Derived class template template class Derived : public Base { public: T doThis() const { return T(); } }; // Derived specialized for void* template<> class Derived : public Base { public: void* doThis() const { return reinterpret_cast(0x0badbeef); } }; // Derived specialized for any pointer template class Derived : public Base, private Derived { public: T* doThis() const { return static_cast(Derived::doThis()); } }; int main() { Derived d; bool b1 = d.doThat(); // Line 37 bool b2 = d.Base::doThat(); bool b3 = d.Base::doThat(); // Line 39 return 0; } pawig@rigel:~/src > g++ -c ctest1.cc ctest1.cc: In function `int main()': ctest1.cc:37: request for member `doThat' is ambiguous ctest1.cc:7: candidates are: bool Base::doThat() const [with T = void*] ctest1.cc:7: bool Base::doThat() const [with T = int*] ctest1.cc:39: `Base' is an inaccessible base of `Derived' >Fix: Workaround: Instead of deriving Derived privately from Derived, just put a Derived data meber into the Derived template. >Release-Note: >Audit-Trail: >Unformatted: