the typename keyword - inheriting types from templated classes

C

Chris Foster

Hi, I'm having some difficulty using types which are defined in a base
class inside a derived class. The problem crops up using template
classes.

The following test code encapsulates what I'd like to do, but doesn't
compile with g++ (v3.3.3).

//---------------------------------------------------------
// A = base class
template <typename T>
class A
{
public:
enum Aenum {foo, bar};
};

// B = class derived from A; inherits type A<T>::Aenum.
template <typename T>
class B : public A<T>
{
public:
Aenum ae;
B(Aenum ae)
{
this->ae = ae;
}
};
//---------------------------------------------------------

When I try to compile, g++ complains with the errors

templtest.cpp:19: warning: `B<T>::Aenum' is implicitly a typename
templtest.cpp:19: warning: implicit typename is deprecated, please see
the documentation for details
templtest.cpp:21: warning: `B<T>::Aenum' is implicitly a typename
templtest.cpp:21: warning: implicit typename is deprecated, please see
the documentation for details

If instead I explicitly tell the compiler that Aenum is a type,
defining the class B by:

//---------------------------------------------------------
template <typename T>
class B : public A<T>
{
public:
typename A<T>::Aenum ae;
B(typename A<T>::Aenum ae = foo)
{
this->ae = ae;
}
};
//---------------------------------------------------------

then the compilation goes without a problem. However, it seems as
though the compiler has all the information it could need to determine
that Aenum is a type from the original definition. Certinally if we
define Aenum within the derived class B rather than the base class A
then there's no problem.

So my question is: is this the behaviour that we *should* expect from
g++, and if so, why?
 
V

Vaclav Haisman

Short: GCC is right.
Longer: You can have e.g. A<int> specialization with Aenum not being type
but something else. There is nice example in C++ Templates - The Complete
Guide:

template<typename T>
class Trap {
public:
enum {x}; // (1) x is not a type here
};

template<typename T>
class Victim
{
public:
int y;
void poof () {
Trap<T>::x * y; // (2) declaration or multiplication?
}
};

template<>
class Trap<void> { // evil specialization
public:
typedef int x; // (3) x is type here
};

void boom (Victim<void> & boom)
{
bomb.poof ();
}

As you can see for Trap<void>::x is type and (2) would mean declaration of
varibable y. But for the generic case it would be multiplication, so to
resolve this ambiguity the compiler assumes variable unless typename is
specified in that case it knows it is a type.

V.H.
 
C

Chris Foster

Short: GCC is right.
Longer: You can have e.g. A<int> specialization with Aenum not being type
but something else. There is nice example in C++ Templates - The Complete
Guide:

template<typename T>
class Trap {
public:
enum {x}; // (1) x is not a type here
};

template<typename T>
class Victim
{
public:
int y;
void poof () {
Trap<T>::x * y; // (2) declaration or multiplication?
}
};

template<>
class Trap<void> { // evil specialization
public:
typedef int x; // (3) x is type here
};

void boom (Victim<void> & boom)
{
bomb.poof ();
}

As you can see for Trap<void>::x is type and (2) would mean declaration of
varibable y. But for the generic case it would be multiplication, so to
resolve this ambiguity the compiler assumes variable unless typename is
specified in that case it knows it is a type.

Aha! Thanks very much, I must confess I'm a little surprised that the
above doesn't result in a name collision (I just need to know more
about how specialisation works I guess :-/ )

It's a pity though, I was hoping I could avoid the notational
nightmare which using the typename keyword causes...

CF
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top