| View previous topic :: View next topic |
| Author |
Message |
Radu Grigore Guest
|
Posted: Tue Aug 17, 2004 7:35 pm Post subject: typedef and inheritance |
|
|
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
|
Posted: Wed Aug 18, 2004 12:13 pm Post subject: Re: typedef and inheritance |
|
|
"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
|
Posted: Wed Aug 18, 2004 6:16 pm Post subject: Re: typedef and inheritance |
|
|
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
|
Posted: Wed Aug 18, 2004 6:21 pm Post subject: Re: typedef and inheritance |
|
|
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
|
Posted: Wed Aug 18, 2004 6:39 pm Post subject: Re: typedef and inheritance |
|
|
[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
|
Posted: Fri Aug 20, 2004 1:00 am Post subject: Re: typedef and inheritance |
|
|
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 |
|
 |
|