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 is often used for that purpose.

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 member template 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)

There are two ways 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>). One way
is to prefix tt(caller's) parameter specification with tt(typename):
    verb(    void caller(typename Outer<T1>::Inner<T2> &obj))
    Although this works, specifying that tt(Outer<T1>::Inner<T2>) is a
typename might looks a bit strange. Therefore. alternatively, the 
ti(::template) construction can be used:
    verb(    void caller(Outer<T1>::template Inner<T2> &obj))
    tt(::template) tells the compiler that the next tt(<) must not be
interpreted as a `less than' token, but rather as a template type
argument.

Of course, tt(caller) itself is not 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) therefore receives a third template type parameter, called
tt(T3). Assuming it has been defined by tt(Usage), then to implement
tt(caller), we write:
        verb(    template <typename T1, typename T2, typename T3>
    void caller(typename Outer<T1>::template Inner<T2> &obj)
    {
        obj.nested<T3>();
    })
    Here again we run into a problem. In the function's body the compiler 
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 is used, as mentioned by the compiler:
    verb(    expected `template' keyword before dependent template name)
    Although issued as a warning, this warning is then followed by error
messages caused by the compiler interpreting tt(<) as `less than'. To remove
the warning and the error messages we write ti(.template) informing
the compiler that what follows is not a `less than' operator, but a
type specification. The function's final implementation thus becomes:
        verb(    template <typename T1, typename T2, typename T3>
    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(    template <typename T1, typename T2, typename T3>
    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
        };
    };)
    But when the derived class itself is a class template this way to
call tt(fun) won't 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 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
        };                                      // (activate typename Tp)
    };)
