5.1 Keyword typename

Ru-Brd

5.1 Keyword typename

The keyword typename was introduced during the standardization of C++ to clarify that an identifier inside a template is a type. Consider the following example:

 template <typename T>  class MyClass {     typename T::SubType * ptr;   }; 

Here, the second typename is used to clarify that SubType is a type defined within class T . Thus, ptr is a pointer to the type T::SubType .

Without typename , SubType would be considered a static member. Thus, it would be a concrete variable or object. As a result, the expression

 T::SubType * ptr 

would be a multiplication of the static SubType member of class T with ptr .

In general, typename has to be used whenever a name that depends on a template parameter is a type. This is discussed in detail in Section 9.3.2 on page 130.

A typical application of typename is the access to iterators of STL containers in template code:

  // basics/printcoll.hpp  #include <iostream>  // print elements of an STL container  template <typename T>  void printcoll (T const& coll)  {      typename T::const_iterator pos;  // iterator to iterate over  coll      typename T::const_iterator end(coll.end());  // end position  for (pos=coll.begin(); pos!=end; ++pos) {          std::cout << *pos << ' ';      }      std::cout << std::endl;  } 

In this function template, the call parameter is an STL container of type T . To iterate over all elements of the container, the iterator type of the container is used, which is declared as type const_iterator inside each STL container class:

 class  stlcontainer  {   typedef   iterator;  // iterator for read/write access  typedef   const_iterator;  // iterator for read access    }; 

Thus, to access type const_iterator of template type T , you have to qualify it with a leading typename :

 typename T::const_iterator pos; 

The .template Construct

A very similar problem was discovered after the introduction of typename . Consider the following example using the standard bitset type:

 template<int N>  void printBitset (std::bitset<N> const& bs)  {      std::cout << bs.template to_string<char,char_traits<char>,                                         allocator<char> >();  } 

The strange construct in this example is .template . Without that extra use of template , the compiler does not know that the less-than token ( < ) that follows is not really "less than" but the beginning of a template argument list. Note that this is a problem only if the construct before the period depends on a template parameter. In our example, the parameter bs depends on the template parameter N .

In conclusion, the .template notation (and similar notations such as ->template ) should be used only inside templates and only if they follow something that depends on a template parameter. See Section 9.3.3 on page 132 for details.

Ru-Brd


C++ Templates
C++ Templates: The Complete Guide
ISBN: 0201734842
EAN: 2147483647
Year: 2002
Pages: 185

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net