When parsing a template-argument-list,
the first non-nested
>116
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.
The second >
token produced by this replacement rule can terminate an enclosing
template-id 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; // syntax error
X<(1>2)> x2; // OKtemplate<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]
[Example 4: template<class T, T::type n =0>class X;
struct S {using type =int;
};
using T1 = X<S, int, int>; // error: too many argumentsusing T2 = X<>; // error: no default argument for first template parameterusing T3 = X<1>; // error: value 1 does not match type-parameterusing T4 = X<int>; // error: substitution failure for second template parameterusing T5 = X<S>; // OK — end example]
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 6: template<typename T>concept C =true;
static_assert(C<int>); // OK — end example]
A > that encloses the type-id
of a dynamic_cast, static_cast, reinterpret_cast
or const_cast, or which encloses the template-arguments
of a subsequent template-id, is considered nested for the purpose
of this description.