[temp.names]

13 Templates [temp]

13.3 Names of template specializations [temp.names]

The component name of a simple-template-id, template-id, or template-name is the first name in it.

A < is interpreted as the delimiter of a template-argument-list if either

[Note 1:

If the name is an identifier, it is then interpreted as a template-name.

The keyword template is used to indicate that a dependent qualified name ([temp.dep.type]) denotes a template where an expression might appear.

— end note]

[Example 1: 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>(); T* p2 = p->template alloc<200>(); T::adjust<100>(); T::template adjust<100>(); static constexpr std::meta::info r = ^^T::adjust; T* p3 = [:r:]<200>(); T* p4 = template [:r:]<200>(); }} — end example]

When parsing a template-argument-list, the first non-nested >103 is taken as the ending delimiter rather than a greater-than operator.

Similarly, the first non-nested >> is treated as two consecutive but distinct > tokens, the first of which is taken as the end of the template-argument-list and completes the template-id or splice-specialization-specifier.

[Note 2:

The second > token produced by this replacement rule can terminate an enclosing template-id or splice-specialization-specifier construct or it can be part of a different construct (e.g., a cast).

— end note]

[Example 2: template<int i> class X { }; X< 1>2 > x1; X<(1>2)> x2; template<class T> class Y { }; Y<X<1>> x3; Y<X<6>>1>> x4; Y<X<(6>>1)>> x5; — end example]

[Example 3: template<int> struct S { }; constexpr int k = 5; constexpr std::meta::info r = ^^k; S<[:r:]> s1; S<([:r:])> s2; S<[:r:] + 1> s3; — end example]

A name prefixed by the keyword template shall be followed by a template argument list or refer to a class template or an alias template.

The keyword template shall not appear immediately before a ~ token (as to name a destructor).

[Note 3:

The keyword template cannot be applied to non-template members of class templates.

— end note]

[Note 4:

As is the case with the typename prefix, the template prefix is well-formed even when lookup for the name would already find a template.

— end note]

[Example 4: 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); a.template f(t); } template <class T> struct B { template <class T2> struct C { }; }; template <class T, template <class X> class TT = T::template C> struct D { }; D<B<int> > db; — end example]

A template-id or splice-specialization-specifier is valid if

  • there are at most as many arguments as there are parameters or a parameter is a template parameter pack ([temp.variadic]),
  • there is an argument for each non-deducible non-pack parameter that does not have a default template-argument,
  • each template-argument matches the corresponding template parameter ([temp.arg]),
  • substitution of each template argument into the following template parameters (if any) succeeds, and
  • if the template-id or splice-specialization-specifier is non-dependent, the associated constraints are satisfied as specified in the next paragraph.

[Example 5: template<class T, T::type n = 0> class X; struct S { using type = int; }; using T1 = X<S, int, int>; using T2 = X<>; using T3 = X<1>; using T4 = X<int>; using T5 = X<S>; — end example]

[Example 6: template<typename T> concept C1 = sizeof(T) != sizeof(int); template<C1 T> struct S1 { }; template<C1 T> using Ptr = T*; S1<int>* p; Ptr<int> p; template<typename T> struct S2 { Ptr<int> x; }; template<typename T> struct S3 { Ptr<T> x; }; S3<int> x; template<template<C1 T> class X> struct S4 { X<int> x; }; template<typename T> concept C2 = sizeof(T) == 1; template<C2 T> struct S { }; template struct S<char[2]>; template<> struct S<char[2]> { }; — end example]

A concept-id is a prvalue of type bool, and does not name a template specialization.

[Note 5:

Since a constraint-expression is an unevaluated operand, a concept-id appearing in a constraint-expression is not evaluated except as necessary to determine whether the normalized constraints are satisfied.

— end note]

[Example 7: template<typename T> concept C = true; static_assert(C<int>); — end example]