You are here:

C++/typename template

Advertisement


Question
the link you sent me was excellent. thank you so much :)

Could you explain the difference between the "typename" here:
template <typename T>
void List<T>::Iterator::next() {
  position = position->next;
}
and here:
template <typename T>
typename List<T>::Iterator List<T>::getLast() const {
  Iterator it;
  it.position = NULL;
  it.last = lastElement;
  return it;
}
why do we have an extra typename there?
if you also have another website that explain this concept, I appreciate it.

Answer
in

template < typename T >
void List<T>::Iterator::next() { position = position->next; }

the typename keyword indicates that the template parameter T is the name of a type. it could alternatively be written as

template < class T >
void List<T>::Iterator::next() { position = position->next; }

in

template <typename T>
typename List<T>::Iterator List<T>::getLast() const { ...
...

the use of typename first line is identical to the one earlier.
the use of typename in the second line is different. let me try to explain:

if we have the following function

template< typename T > void a_function( T& arg )
{
  T::some_name * pointer ;
  // ...
}

what T::some_name means, is not known till we know what T is.
for example, if we have a class

class contains_a_type_some_name
{
  public: typedef int some_name ;
};

and we instantiate the template with T as contains_a_type_some_name,
T::some_name is an int (a type).

if we have another class contains_a_value_some_name

class contains_a_value_some_name
{
  public: static int some_name ;
};

and we instantiate the template with T as contains_a_value_some_name,
T::some_name is a variable (not a type).

the meaning of

T::some_name * pointer ;

changes depending on what T is. in our example,
a. if T is contains_a_type_some_name, we are declaring iterator to be a pointer to an int.
b. if T is contains_a_value_some_name, we are multiplying an int variable with another variable called pointer.

a name like some_name in the above example is called a 'dependent name'. the meaning of the name depends on what T is. the same sequence of tokens can be parsed in two entirely different ways (depending on what T is), and there's no way to decide which is right.

to get over this problem, the parsing rule for C++ is that dependent names should be parsed as non-types (even if it leads to a syntax error). the typename keyword is used to disambiguate this; if we write

template< typename T > void a_function( T& arg )
{
  typename T::some_name * pointer ;
  // ...
}

we tell the compiler that the name that follows ( T::some_name ) is to be parsed as the name of a type. without it, the name are interpreted to refer to non-types.

in

template <typename T>
typename List<T>::Iterator List<T>::getLast() const { ...

typename in the second line clarifies to the compiler that the dependent name List<T>::Iterator is to be treated as the name of a type.

here is a link with a more detailed explanation: http://pages.cs.wisc.edu/~driscoll/typename.html  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.