views:

94

answers:

2

Possible Duplicate:
Officially, what is typename for?

When I use

template <typename TMap>
typename TMap::referent_type * func(TMap & map, typename TMap::key_type key) 
{ ... }

what is the purpose of the two "typename"'s on the second line?

It seems to trigger a compile-time warning (VS2008: C4346) but it's only a "do you claim this to be a type"?

i.e. the actual check if TMap::referent_type is actually type is made when the template gets instantiated, but there still seems to be a requirement by the C++ standard, but the code being parsed correctly regarless.

Are there any examples where the typename is actually required to resolve an ambiguity? Or is there more to that?

+3  A: 

The typename keyword just tells the compiler that whatever identifier follows is a valid type. This is important in templates because the compiler may not yet have the definitions of the types used in the templates, but you still want to be able to use part of that type's definition (e.g., like key_type above). If you didn't use the typename keyword, the compiler would error out on that symbol because it doesn't know what it is. This comes in to play often when you use template instances as template parameters.

Clear as mud?

Ben Collins
+1 - To (hopefully) clarify a little, within a template, if you have Shape::type, the compiler can't discern if type is a "type" or if it's a variable/enum within Shape. Using the typename qualifier allows you to tell the compiler that this is a "type".
RC
A: 

You have to use typename when the type which you are using is depended to another thing.

In your example, TMap::key_type is depended to the template argument and TMap::key_type may be a function identifier or a variable name or anything else... so we have to ensure the compiler that is a type not a member function/variable.

On the other hand, when the type which we are using are not depended on another templates, then we don't need to specify that as a typename.

PC2st