By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,928 Members | 1,173 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,928 IT Pros & Developers. It's quick & easy.

the typename keyword - inheriting types from templated classes

P: n/a
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?
Jul 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
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.

"Chris Foster" <c4**@yahoo.com.au> wrote in message
news:ff**************************@posting.google.c om...
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?

Jul 22 '05 #2

P: n/a
> 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
Jul 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.