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 of
type-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:

- 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 logical AND expression whose operands are in the following order:
- the constraint-expression introduced by each type-constraint 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, 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

: *end example*

]template<typename T> concept C = true; template<C T> void f1(T); template<typename T> requires C<T> void f2(T); template<typename T> void f3(T) requires C<T>;

template<typename T> concept C1 = true; template<typename T> concept C2 = sizeof(T) > 0; template<C1 T> void f4(T) requires C2<T>; template<typename T> requires C1<T> && C2<T> void f5(T);

template<C1 T> requires C2<T> void f6(); template<C2 T> requires C1<T> void f7();—