In general, the compiler is able to determine the true nature of a name. As
discussed, this is not always the case and sometimes we have to advise the
compiler. The tt(typename) keyword may often be used for that purpose.

But tt(typename) cannot always come to the rescue. While parsing a source the
compiler receives a series of em(tokens), representing meaningful units of
text encountered in the program's source. A token could represent, e.g., an
identifier or a number. Other tokens represent operators, like tt(=, +) or
tt(<). It is precisely the last token that may cause problems as it may have
very different meanings. The correct meaning cannot always be determined from
the context in which the compiler encounters tt(<). In some situations the
compiler em(does) know that tt(<) does not represent the em(less than)
operator, as when a template parameter list follows the keyword tt(template),
e.g.,
        verb(
    template <typename T, int N>
        )
    Clearly, in this case tt(<) does not represent a `less than' operator.

The special meaning of tt(<) when it is preceded by tt(template) forms the
basis for the syntactic constructs discussed in this section.

    Assume the following class has been defined:
        verb(
    template <typename Type>
    class Outer
    {
        public:
            template <typename InType>
            class Inner
            {
                public:
                    template <typename X>
                    void nested();
            };
    };
        )
    The class template tt(Outer) defines a nested class template
tt(Inner). tt(Inner) in turn defines a template member function.

    Next a class template tt(Usage) is defined, offering a member function
tt(caller) expecting an object of the above tt(Inner) type.  An initial setup
for tt(Usage) looks like this:
        verb(
    template <typename T1, typename T2>
    class Usage
    {
        public:
            void caller(Outer<T1>::Inner<T2> &obj);
       ...
    };
        )
    The compiler won't accept this as it interprets tt(Outer<T1>::Inner) as a
class type. But there is no class tt(Outer<T1>::Inner). Here the compiler
generates an error like:
        verb(
    error: 'class Outer<T1>::Inner' is not a type
        )
    To inform the compiler that tt(Inner)
 hi(template: specified within template)
 hi(template: and the < token)
    itself is a template, using the template type parameter tt(<T2>), the
ti(::template) construction is required. It tells the compiler that the next
tt(<) should not be interpreted as a `less than' token, but rather as a
template type argument. So, the declaration is modified to:
        verb(
    void caller(Outer<T1>::template Inner<T2> &obj);
        )
    This still doesn't get us where we want to be: after all tt(Inner<T2>) is
a type, nested under a class template, depending on a template type
parameter. In fact, the original tt(Outer<T1>::Inner<T2> &obj) declaration
results in a series of error messages, one of them looking like this:
        verb(
    error: expected type-name before '&' token
        )
    As is often the case this error message nicely indicates what should be
done to get it right: add tt(typename):
        verb(
    void caller(typename Outer<T1>::template Inner<T2> &obj);
        )

    Of course, tt(caller) itself is not only just declared, it must also be
implemented. Assume that its implementation should call tt(Inner)'s member
tt(nested), instantiated for yet another type tt(X). The class template
tt(Usage) should therefore receive a third template type parameter, called
tt(T3). Assume it has been defined. To implement tt(caller), we write:
        verb(
    void caller(typename Outer<T1>::template Inner<T2> &obj)
    {
        obj.nested<T3>();
    }
        )
   Once again we run into a problem. In the function's body the compiler once
again interprets tt(<) as `less than', seeing a logical expression having as
its right-hand side a primary expression instead of a function call specifying
a template type tt(T3).

    To tell the compiler that is should interpret tt(<T3>) as a type to
instantiate, the tt(template) keyword must once again be used. This
time it is used in the context of the member selection operator.  We write
ti(.template) to inform the compiler that what follows is not a `less than'
operator, but rather a type specification. The function's final implementation
becomes:
        verb(
    void caller(typename Outer<T1>::template Inner<T2> &obj)
    {
        obj.template nested<T3>();
    }
        )

    Instead of defining value or reference parameters functions may also
define pointer parameters. Had tt(obj) been defined as a pointer parameter the
implementation would have had to use the tt(->template) construction, rather
than the tt(.template) construction. E.g.,
        verb(
    void caller(typename Outer<T1>::template Inner<T2> *ptr)
    {
        ptr->template nested<T3>();
    }
        )

As we've seen class templates can be derived from base class templates. The
base class template can declare a i(static member template), which is
available to a class that is derived from this base class. Such a base class
might look like this:
        verb(
    template <typename Type>
    struct Base
    {
        template <typename Tp>
        static void fun();
    };
        )

    Normally, when a base class defines a static member we can just call that
member by prefixing its name by its class name. E.g.,
        verb(
    int main()
    {
        Base<int>::fun<double>();
    }
        )
    This also works fine if a class tt(Derived) is derived from tt(Base),
instantiated for a specific type:
        verb(
    struct Der: public Base<int>
    {
        static void call()
        {
            Base<int>::fun<int>();      // OK
            fun<int>();                 // also OK
        };
    };
        )
    However, when the derived class itself is a class template this way to
call tt(fun) does not compile anymore, as it interprets tt(Base<Type>::fun) in
tt(Base<Type>::fun<int>) as a type, to be instantiated for tt(int). This
interpretation can be overruled by us by indicating that tt(fun) itself is a
template. For this the tt(::template) prefix is used:
        verb(
    template <typename Type>
    struct Der: public Base<Type>
    {
        //template <typename Tp>    // 'call' may be a member template
        //static                    // 'call' may be a static member
        void call()
        {
            // fun<int>();                      // won't compile
            // Base<Type>::fun<int>();          // won't compile
            Base<Type>::template fun<int>();    // OK
            Base<Type>::template fun<Tp>();     // OK if call is a 
                                                //    member template
        };
    };
        )
