C++ Study Note (3) - typename, class and template


C++ is strong type-safe language, the C++ compiler needs to check type and verify syntax correctness. C++ reuse the * as pointer dereference, also multiple, the template reuse the < >, which might be used in the stream >> or logic operation, (less than, great than). C++ compiler may not figure out the ambiguous syntax meaning in some cases, for example:

template< class T, typename U> foo;

foo< int, vector<int>> v;

iterator_traits<FwdIterator1>::value_type* pi = &*i;

template <typename T, typename T::value_type>  struct sqrt_impl;

{  return  x.convert<3>(pi);  }

Ln 1 demonstrates either class or typename can be used to declare the template parameter.

Ln 2 shows a pitfall for > >, if there is no space between two >, the compiler would regards it as >> stream operator instead.

Ln 3 – 5 are copied from text book B1.1

Ln 3 is a typical case when to use typename. The compiler could not determine whether iterator_traits::value_type is a type or a value. If it is a type, _ would be the pointer decorator, otherwise, _ is the multiplex. We need to help the compiler to clarify the ambiguousness by adding typename decorator like this: typename iterator_traits::value_type

Ln 4 is the example of misusing typename as the template parameter. typename T::value_type could also be regarded as the typename declaration. The best approach is to use class only.

Ln 5 is the example when to use template keyword to disambiguate template. x.convert could be a template member function or member variable; therefore, the succeeding < can be interpreted as either template or less than, great than operators. The work-around is like this: { return x.template convert(pi); }

Here are some rules of thumbs:

  • typename is required anywhere in templates on qualified dependent names that denote type.
  • typename is forbidden on the name of base class.
  • template is required before dependent names accessing member templates via ., ->, or :: qualification.