6.7 KiB
[temp.constr.decl]
13 Templates [temp]
13.5 Template constraints [temp.constr]
13.5.3 Constrained declarations [temp.constr.decl]
A template declaration ([temp.pre]) or templated function declaration ([dcl.fct]) can be constrained by the use of a requires-clause.
This allows the specification of constraints for that declaration as an expression:
constraint-expression:
logical-or-expression
Constraints can also be associated with a declaration through the use oftype-constraints in a template-parameter-list or parameter-type-list.
Each of these forms introduces additional constraint-expressions that are used to constrain the declaration.
A declaration's associated constraints are defined as follows:
-
If there are no introduced constraint-expressions, the declaration has no associated constraints.
-
Otherwise, if there is a single introduced constraint-expression, the associated constraints are the normal form of that expression.
-
Otherwise, the associated constraints are the normal form of a logicaland expression whose operands are in the following order:
the constraint-expression introduced by each type-constraint ([temp.param]) in the declaration's template-parameter-list, in order of appearance, and
the constraint-expression introduced by a requires-clause following a template-parameter-list ([temp.pre]), and
the constraint-expression introduced by each type-constraint in the parameter-type-list of a function declaration, and
the constraint-expression introduced by a trailing requires-clause ([dcl.decl]) of a function declaration ([dcl.fct]).
The formation of the associated constraints establishes the order in which constraints are instantiated when checking for satisfaction ([temp.constr.constr]).
[Example 1: template concept C = true;
template void f1(T);template requires C void f2(T);template void f3(T) requires C;
The functions f1, f2, and f3 have the associated constraint C.
template concept C1 = true;template concept C2 = sizeof(T) > 0;
template void f4(T) requires C2;template requires C1 && C2 void f5(T);
The associated constraints of f4 and f5 are C1 â§ C2.
template requires C2 void f6();template requires C1 void f7();
The associated constraints off6 are C1 â§ C2, and those off7 are C2 â§ C1.
â end example]
When determining whether a given introducedconstraint-expression C1 of a declaration in an instantiated specialization of a templated class is equivalent ([temp.over.link]) to the correspondingconstraint-expression C2 of a declaration outside the class body,C1 is instantiated.
If the instantiation results in an invalid expression, the constraint-expressions are not equivalent.
[Note 1:
This can happen when determining which member template is specialized by an explicit specialization declaration.
â end note]
[Example 2: template concept C = true;template struct A {template U f(U) requires C; // #1template U f(U) requires C; // #2};
template <> template U A::f(U u) requires C { return u; } // OK, specializes #2
Substituting int for T in C<typename T::type> produces an invalid expression, so the specialization does not match #1.
Substituting int for T in C produces C, which is equivalent to the constraint-expression for the specialization, so it does match #2.
â end example]