[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
- it follows a splice-specifier that either
- appears in a type-only context or
- is preceded by template or typename, or
- it follows a name that is not a conversion-function-id and
- that follows the keyword template or a ~ after a nested-name-specifier or in a class member access expression, or
- for which name lookup finds the injected-class-name of a class template or finds any declaration of a template, or
- that is an unqualified name for which name lookup either finds one or more functions or finds nothing, or
- that is a terminal name in a using-declarator ([namespace.udecl]), in a declarator-id ([dcl.meaning]), or in a type-only context other than a nested-name-specifier ([temp.res]).
[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]