simple-template-id: template-name < template-argument-list >
template-id: simple-template-id operator-function-id < template-argument-list > literal-operator-id < template-argument-list >
template-name: identifier
template-argument-list: template-argument ... template-argument-list , template-argument ...
template-argument: constant-expression type-id id-expression
template<int i> class X { /* ... */ };
X< 1>2 > x1;                            // syntax error
X<(1>2)> x2;                            // OK
template<class T> class Y { /* ... */ };
Y<X<1>> x3;                             // OK, same as Y<X<1> > x3;
Y<X<6>>1>> x4;                          // syntax error
Y<X<(6>>1)>> x5;                        // OK
 — end example
struct X {
  template<std::size_t> X* alloc();
  template<std::size_t> static X* adjust();
};
template<class T> void f(T* p) {
  T* p1 = p->alloc<200>();              // ill-formed: < means less than
  T* p2 = p->template alloc<200>();     // OK: < starts template argument list
  T::adjust<100>();                     // ill-formed: < means less than
  T::template adjust<100>();            // OK: < starts template argument list
} — end example
template <class T> struct A {
  void f(int);
  template <class U> void f(U);
};
template <class T> void f(T t) {
  A<T> a;
  a.template f<>(t);                    // OK: calls template
  a.template f(t);                      // error: not a template-id
}
template <class T> struct B {
  template <class T2> struct C { };
};
// OK: T::template C names a class template:
template <class T, template <class X> class TT = T::template C> struct D { };
D<B<int> > db; — end example