c++/8875: Ambiguities in mixed template hierarchies
pawig@hildesheim.sgh-net.de
pawig@hildesheim.sgh-net.de
Sun Dec 8 10:56:00 GMT 2002
>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<int*> in the sample code): the compiler
complains that the concrete member is ambiguous (line 37).
Using explicit qualification works for Base<int*>::doThat() but
fails for Base<void*>::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 <typename T>
class Base
{
public:
virtual T doThis() const = 0;
bool doThat() const { return doThis() == T(); }
};
// General Derived class template
template <typename T>
class Derived : public Base<T>
{
public:
T doThis() const { return T(); }
};
// Derived specialized for void*
template<>
class Derived<void*> : public Base<void*>
{
public:
void* doThis() const { return reinterpret_cast<void*>(0x0badbeef); }
};
// Derived specialized for any pointer
template <typename T>
class Derived<T*> : public Base<T*>, private Derived<void*>
{
public:
T* doThis() const { return static_cast<T*>(Derived<void*>::doThis()); }
};
int main()
{
Derived<int*> d;
bool b1 = d.doThat(); // Line 37
bool b2 = d.Base<int*>::doThat();
bool b3 = d.Base<void*>::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<T>::doThat() const [with T = void*]
ctest1.cc:7: bool Base<T>::doThat() const [with T = int*]
ctest1.cc:39: `Base<void*>' is an inaccessible base of `Derived<int*>'
>Fix:
Workaround:
Instead of deriving Derived<T*> privately from Derived<void*>,
just put a Derived<void*> data meber into the Derived<T*> template.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the Gcc-prs
mailing list