C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

typedef and inheritance

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Radu Grigore
Guest





PostPosted: Tue Aug 17, 2004 7:35 pm    Post subject: typedef and inheritance Reply with quote



Why isn't visible the typedef in the base class?

=== begin code ===
#include <iostream>
using namespace std;

template <typename T>
class B {public: typedef T type; };

template <typename T>
class D : public B<T> { // (1)
public:
void print(type t) { cout << t << endl; } // (2)
};

int main()
{
D d.print(10);
}
=== end code ===

The compiler complains on line (2) about not knowing what is "type".
If you change B<T> to B<int> on line (1) it compiles & runs. Why? One
way to "fix" it is to redeclare the type in class D:
typedef typename B<T>::type type;
Is there a better way _without_ modifying class B?

regards,
radu

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Victor Bazarov
Guest





PostPosted: Wed Aug 18, 2004 12:13 pm    Post subject: Re: typedef and inheritance Reply with quote



"Radu Grigore" <radugrigore (AT) gmail (DOT) com> wrote...
Quote:
Why isn't visible the typedef in the base class?

=== begin code ===
#include <iostream
using namespace std;

template class B {public: typedef T type; };

template class D : public B public:
void print(type t) { cout << t << endl; } // (2)
};

int main()
{
D d.print(10);
}
=== end code ===

The compiler complains on line (2) about not knowing what is "type".

Rightly so. See 14.6.2/3.

Quote:
If you change B<T> to B<int> on line (1) it compiles & runs. Why? One
way to "fix" it is to redeclare the type in class D:
typedef typename B<T>::type type;
Is there a better way _without_ modifying class B?

Another way is to fully qualify the 'type':

void print(typename B<T>::type t) { cout << t << endl; } // (2)

Victor


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Marco Manfredini
Guest





PostPosted: Wed Aug 18, 2004 6:16 pm    Post subject: Re: typedef and inheritance Reply with quote



Radu Grigore wrote:

Quote:
Why isn't visible the typedef in the base class?

void print(type t) { cout << t << endl; } // (2)
void print(typename B


You can't use 'type' implicitly, because when the compiler reads the
definition of D<> it has no idea what 'type' is supposed to mean. This
is because you want 'type' to come from a base class that depends on
the template parameter, and is therefore undecided yet.
That's the main difference to when you say B<int> instead: The compiler
sees that there is a typedef 'type' in B<int>...If you say just B<T>,
then things could change unexpectedly, for example when you add a
specialization:

template<>
class B<int>
{
enum XY { type=1 };
};

D<int> would have a 'type' now that is an enum constant.

The hole cruft is necessary, because it was decided that the compiler
should have enough informations to parse template definitions when he
sees them.

Marco



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Daniel Krügler (ne Spange
Guest





PostPosted: Wed Aug 18, 2004 6:21 pm    Post subject: Re: typedef and inheritance Reply with quote

Hello Radu Grigore,

Radu Grigore schrieb:

Quote:
Why isn't visible the typedef in the base class?

=== begin code ===
#include <iostream
using namespace std;

template class B {public: typedef T type; };

template class D : public B public:
void print(type t) { cout << t << endl; } // (2)
};

int main()
{
D d.print(10);
}
=== end code ===

The compiler complains on line (2) about not knowing what is "type".
If you change B<T> to B<int> on line (1) it compiles & runs. Why?


Due to the possibility of specializations of the base class template.
Consider the following
legal specialization for B:

template <>
class B<int> { };


or even worse:

template <>
class B<int> { public: enum E { type }; };


or this:

template <typename T>
class B {private: typedef T type; };


By deriving D from B<int> instead of B<T> you derive from a fully
instantiated class
which's complete definition is no longer delayed (This is the same
behaviour as if
you would derive from BConcrete, where class BConcrete{public: typedef
int type; }; )

Quote:
One
way to "fix" it is to redeclare the type in class D:
typedef typename B<T>::type type;
Is there a better way _without_ modifying class B?



An alternative is

using typename B<T>::type;


or direct usage of typename D<T>::type in the derived class. The second
usage has the advantage, that it works with any non-ambigious name type
from
the complete D inheritance hierachy.

Greetings from Bremen,

Daniel Krügler




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
gorda
Guest





PostPosted: Wed Aug 18, 2004 6:39 pm    Post subject: Re: typedef and inheritance Reply with quote

[email]radugrigore (AT) gmail (DOT) com[/email] (Radu Grigore) wrote in message news:<7f8e92aa.0408170406.6898eee9 (AT) posting (DOT) google.com>...
Quote:
Why isn't visible the typedef in the base class?

=== begin code ===
#include <iostream
using namespace std;

template class B {public: typedef T type; };

template class D : public B public:
void print(type t) { cout << t << endl; } // (2)
};

int main()
{
D d.print(10);
}
=== end code ===

The compiler complains on line (2) about not knowing what is "type".
If you change B<T> to B<int> on line (1) it compiles & runs. Why? One
way to "fix" it is to redeclare the type in class D:
typedef typename B<T>::type type;
Is there a better way _without_ modifying class B?

regards,
radu


Hmm, there doesn't seem to be any problem, and when i ran your code as
you posted, it worked on my machine. What compiler version are you
using?
I'm using: gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Daniel Krügler (ne Spange
Guest





PostPosted: Fri Aug 20, 2004 1:00 am    Post subject: Re: typedef and inheritance Reply with quote

Hello gorda,

gorda schrieb:

Quote:
Hmm, there doesn't seem to be any problem, and when i ran your code as
you posted, it worked on my machine. What compiler version are you
using?
I'm using: gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110)



It shouldn't compile successfully, for the reasons see the other
postings. gcc 2.96 is a rather
old compiler and is not aware of all standard rules concerning tamplates
(and some other
issues). Even 3.2 does erroneously accept the code (I assume 3.4
doesn't, but
I can't test it here)

Greetings from Bremen,

Daniel


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.