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; / 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 3: template<int>struct S {};
constexprint k =5;
constexpr std::meta::info r =^^k;
S<[:r:]> s1; / error: unparenthesized splice-expression used as template argument
S<([:r:])> s2; / OK
S<[:r:]+1> s3; / OK — end example]
[Example 5: 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 7: template<typename T>concept C =true;
static_assert(C<int>); / OK — end example]