On occasion I've seen some really indecipherable error messages spit out by gcc when using templates... Specifically, I've had problems where seemingly correct declarations were causing very strange compile errors that magically went away by prefixing the "typename" keyword to the beginning of the declaration... (For example, just last week, I was declaring two iterators as members of another templated class and I had to do this)...
What's the story on typename?
In some situations where you refer to a member of so called dependent type (meaning "dependent on template parameter"), the compiler cannot always unambiguously deduce the semantic meaning of the resultant construct, because it doesn't know what kind of name that is (i.e. whether it is a name of a type, a name of a data member or name of something else). In cases like that you have to disambiguate the situation by explicitly telling the compiler that the name belongs to a typename defined as a member of that dependent type.
For example
In this example the keyword
typename
in necessary for the code to compile.The same thing happens when you want to refer to a template member of dependent type, i.e. to a name that designates a template. You also have to help the compiler by using the keyword
template
, although it is placed differentlyIn some cases it might be necessary to use both
(if I got the syntax correctly).
Of course, another role of the keyword
typename
is to be used in template parameter declarations.Two uses:
The secret lies in the fact that a template can be specialized for some types. This means it also can define the interface completely different for several types. For example you can write:
One might ask why is this useful and indeed: That really looks useless. But take in mind that for example
std::vector<bool>
thereference
type looks completely different than for otherT
s. Admittedly it doesn't change the kind ofreference
from a type to something different but nevertheless it could happen.Now what happens if you write your own templates using this
test
template. Something like thisit seems to be ok for you because you expect that
test<T>::ptr
is a type. But the compiler doesn't know and in deed he is even advised by the standard to expect the opposite,test<T>::ptr
isn't a type. To tell the compiler what you expect you have to add atypename
before. The correct template looks like thisBottom line: You have to add
typename
before whenever you use a nested type of a template in your templates. (Of course only if a template parameter of your template is used for that inner template.)Following is the quote from Josuttis book:
Stan Lippman's BLog post suggests :-
So basically Stroustrup reused class keyword without introducing a new keyword which is changed afterwards in the standard for the following reasons
As the example given
language grammar misinterprets
T::A *aObj;
as an arithmetic expression so a new keyword is introduced calledtypename
it instructs the compiler to treat the subsequent statement as a declaration.
Thats why we have both
You can have a look at this post, it will definitely help you, I just extracted from it as much as I could