473,378 Members | 1,531 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

the typename keyword - inheriting types from templated classes

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
2 2668
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
> 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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Rim | last post by:
Hi, With the great unification of types and classes, what will happen to the following identity inconsistency? >>> class myint(int): pass .... >>> a=int(1); b=int(1) >>> a is b 1
2
by: Anonymous | last post by:
I'm trying to port code from VC.net to VC.net 2003. Here's a typical piece of code that's often used: template<class T> class PseudoContainer { typedef T::iterator iterator; // this line will...
0
by: Chris Jefferson | last post by:
Now, C++ doesn't actually provide true variable-length templated classes, for example you can't do (as I found recently!) template<class T> class tuple { ... } template<class T, class U>...
2
by: Peter Bates | last post by:
Hi, I'm just getting used to XSDObjectGen and i have the following question. Can i use a class inherited from a class generated by XSDObjectGen with XmlSerialize? Specifically, I have many...
4
by: Jeremy | last post by:
Hi Guys, How do I get all the inheriting types of a specific type I guess I can get this using reflection... Could someone pls point me to an example or resource thanks
12
by: Robert.Holic | last post by:
Hi All (first time caller, long time listener), I've stumbled across a problem that I have yet to figure out, although Im sure I'll kick myself when I figure it out. Here it is: I need to...
1
by: cpunerd | last post by:
Hello, I'm not new to C++, but for some reason, until now I'd never had a need for deriving templated classes. Now though, I find myself seeing a weird problem. If I have a templated base class...
5
by: lobequadrat | last post by:
Hello, I am trying to get the following code work (unfortunately not mine ... :( ) template <class Tclass Test { public: class ELEM;
2
card
by: card | last post by:
Hi everyone, I have a question about referencing a nested class contained within a templated class. Of course the best way to show you is by example. Here's my templated classes: #include...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.