C++ Study Note (3) - typename, class and template
cppC++ 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.