Files
2025-10-25 03:02:53 +03:00

6.7 KiB
Raw Permalink Blame History

[temp.constr.decl]

13 Templates [temp]

13.5 Template constraints [temp.constr]

13.5.3 Constrained declarations [temp.constr.decl]

1

#

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

2

#

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.

3

#

A declaration's associated constraints are defined as follows:

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]

4

#

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]