[temp.constr]

# 13 Templates [[temp]](./#temp)

## 13.5 Template constraints [temp.constr]

### [13.5.1](#general) General [[temp.constr.general]](temp.constr.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1595)

[*Note [1](#general-note-1)*:

Subclause [temp.constr] defines the meaning of constraints on template arguments[.](#general-1.sentence-1)

The abstract syntax and satisfaction rules are defined
in [[temp.constr.constr]](#constr "13.5.2 Constraints")[.](#general-1.sentence-2)

Constraints are associated with declarations in [[temp.constr.decl]](#decl "13.5.3 Constrained declarations")[.](#general-1.sentence-3)

Declarations are partially ordered by their associated constraints ([[temp.constr.order]](#order "13.5.5 Partial ordering by constraints"))[.](#general-1.sentence-4)

â *end note*]

### [13.5.2](#constr) Constraints [[temp.constr.constr]](temp.constr.constr)

#### [13.5.2.1](#constr.general) General [[temp.constr.constr.general]](temp.constr.constr.general)

[1](#constr.general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1610)

A [*constraint*](#def:constraint "13.5.2.1 General [temp.constr.constr.general]") is a sequence of logical operations and
operands that specifies requirements on template arguments[.](#constr.general-1.sentence-1)

The operands of a logical operation are constraints[.](#constr.general-1.sentence-2)

There are five different kinds of constraints:

- [(1.1)](#constr.general-1.1)

conjunctions ([[temp.constr.op]](#op "13.5.2.2 Logical operations")),

- [(1.2)](#constr.general-1.2)

disjunctions ([[temp.constr.op]](#op "13.5.2.2 Logical operations")),

- [(1.3)](#constr.general-1.3)

atomic constraints ([[temp.constr.atomic]](#atomic "13.5.2.3 Atomic constraints")),

- [(1.4)](#constr.general-1.4)

concept-dependent constraints ([[temp.constr.concept]](#concept "13.5.2.4 Concept-dependent constraints")), and

- [(1.5)](#constr.general-1.5)

fold expanded constraints ([[temp.constr.fold]](#fold "13.5.2.5 Fold expanded constraint"))[.](#constr.general-1.sentence-3)

[2](#constr.general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1623)

In order for a constrained template to be instantiated ([[temp.spec]](temp.spec "13.9 Template instantiation and specialization")),
its [associated constraints](#def:associated_constraints "13.5.3 Constrained declarations [temp.constr.decl]") shall be satisfied as described in the following subclauses[.](#constr.general-2.sentence-1)

[*Note [1](#constr.general-note-1)*:

Forming the name of a specialization of
a class template,
a variable template, or
an alias template ([[temp.names]](temp.names "13.3 Names of template specializations"))
requires the satisfaction of its constraints[.](#constr.general-2.sentence-2)

[Overload resolution](over.match.viable "12.2.3 Viable functions [over.match.viable]") requires the satisfaction of constraints
on functions and function templates[.](#constr.general-2.sentence-3)

â *end note*]

#### [13.5.2.2](#op) Logical operations [[temp.constr.op]](temp.constr.op)

[1](#op-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1640)

There are two binary logical operations on constraints: conjunction
and disjunction[.](#op-1.sentence-1)

[*Note [1](#op-note-1)*:

These logical operations have no corresponding C++ syntax[.](#op-1.sentence-2)

For the purpose of exposition, conjunction is spelled
using the symbol  â§  and disjunction is spelled using the
symbol  â¨ [.](#op-1.sentence-3)

The operands of these operations are called the left
and right operands[.](#op-1.sentence-4)

In the constraint A â§ B,A is the left operand, and B is the right operand[.](#op-1.sentence-5)

â *end note*]

[2](#op-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1653)

A [*conjunction*](#def:conjunction "13.5.2.2 Logical operations [temp.constr.op]") is a constraint taking two
operands[.](#op-2.sentence-1)

To determine if a conjunction is[*satisfied*](#def:constraint,satisfaction,conjunction "13.5.2.2 Logical operations [temp.constr.op]"),
the satisfaction of
the first operand is checked[.](#op-2.sentence-2)

If that is not satisfied, the conjunction is not satisfied[.](#op-2.sentence-3)

Otherwise, the conjunction is satisfied if and only if the second
operand is satisfied[.](#op-2.sentence-4)

[3](#op-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1664)

A [*disjunction*](#def:disjunction "13.5.2.2 Logical operations [temp.constr.op]") is a constraint taking two
operands[.](#op-3.sentence-1)

To determine if a disjunction is[*satisfied*](#def:constraint,satisfaction,disjunction "13.5.2.2 Logical operations [temp.constr.op]"),
the satisfaction of
the first operand is checked[.](#op-3.sentence-2)

If that is satisfied, the disjunction is satisfied[.](#op-3.sentence-3)

Otherwise, the disjunction is satisfied if and only if the second
operand is satisfied[.](#op-3.sentence-4)

[4](#op-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1676)

[*Example [1](#op-example-1)*: template<typename T>constexpr bool get_value() { return T::value; }template<typename T>requires (sizeof(T) > 1) && (get_value<T>())void f(T); // has associated constraint sizeof(T) > 1  â§  get_value<T>()void f(int);

f('a'); // OK, calls f(int)

In the satisfaction of the [associated constraints](#def:associated_constraints "13.5.3 Constrained declarations [temp.constr.decl]") of f, the constraint sizeof(char) > 1 is not satisfied;
the second operand is not checked for satisfaction[.](#op-4.sentence-1)

â *end example*]

[5](#op-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1695)

[*Note [2](#op-note-2)*:

A logical negation expression ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")) is an atomic constraint;
the negation operator is not treated as a logical operation on constraints[.](#op-5.sentence-1)

As a result, distinct negation [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]")*s* that are equivalent under [[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading") do not subsume one another under [[temp.constr.order]](#order "13.5.5 Partial ordering by constraints")[.](#op-5.sentence-2)

Furthermore, if substitution to determine
whether an atomic constraint is satisfied ([[temp.constr.atomic]](#atomic "13.5.2.3 Atomic constraints"))
encounters a substitution failure, the constraint is not satisfied,
regardless of the presence of a negation operator[.](#op-5.sentence-3)

[*Example [2](#op-example-2)*: template <class T> concept sad = false;

template <class T> int f1(T) requires (!sad<T>);template <class T> int f1(T) requires (!sad<T>) && true;int i1 = f1(42); // ambiguous, !sad<T> atomic constraint expressions ([[temp.constr.atomic]](#atomic "13.5.2.3 Atomic constraints"))// are not formed from the same [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]")template <class T> concept not_sad = !sad<T>;template <class T> int f2(T) requires not_sad<T>;template <class T> int f2(T) requires not_sad<T> && true;int i2 = f2(42); // OK, !sad<T> atomic constraint expressions both come from not_sadtemplate <class T> int f3(T) requires (!sad<typename T::type>);int i3 = f3(42); // error: associated constraints not satisfied due to substitution failuretemplate <class T> concept sad_nested_type = sad<typename T::type>;template <class T> int f4(T) requires (!sad_nested_type<T>);int i4 = f4(42); // OK, substitution failure contained within sad_nested_type

Here,requires (!sad<typename T​::​type>) requires
that there is a nested type that is not sad,
whereasrequires (!sad_nested_type<T>) requires
that there is no sad nested type[.](#op-5.sentence-4)

â *end example*]

â *end note*]

#### [13.5.2.3](#atomic) Atomic constraints [[temp.constr.atomic]](temp.constr.atomic)

[1](#atomic-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1738)

An [*atomic constraint*](#def:constraint,atomic "13.5.2.3 Atomic constraints [temp.constr.atomic]") is formed from
an expression E and a mapping from the template parameters
that appear within E to
template arguments that are formed via substitution during constraint normalization
in the declaration of a constrained entity (and, therefore, can involve the
unsubstituted template parameters of the constrained entity),
called the [*parameter mapping*](#def:parameter_mapping "13.5.2.3 Atomic constraints [temp.constr.atomic]") ([[temp.constr.decl]](#decl "13.5.3 Constrained declarations"))[.](#atomic-1.sentence-1)

[*Note [1](#atomic-note-1)*:

Atomic constraints are formed by [constraint normalization](#def:constraint,normalization "13.5.4 Constraint normalization [temp.constr.normal]")[.](#atomic-1.sentence-2)

E is never a [logical and expression](expr.log.and "7.6.14 Logical AND operator [expr.log.and]") nor a [logical or expression](expr.log.or "7.6.15 Logical OR operator [expr.log.or]")[.](#atomic-1.sentence-3)

â *end note*]

[2](#atomic-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1753)

Two atomic constraints, e1 and e2, are[*identical*](#def:atomic_constraint,identical "13.5.2.3 Atomic constraints [temp.constr.atomic]") if they are formed from the same appearance of the same[*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") and if, given a hypothetical template A whose [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") consists of[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* corresponding and equivalent ([[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading")) to
those mapped by the parameter mappings of the expression,
a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") naming A whose [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* are
the targets of the parameter mapping of e1 is the same ([[temp.type]](temp.type "13.6 Type equivalence")) as
a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") naming A whose [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* are
the targets of the parameter mapping of e2[.](#atomic-2.sentence-1)

[*Note [2](#atomic-note-2)*:

The comparison of parameter mappings of atomic constraints
operates in a manner similar to that of declaration matching
with alias template substitution ([[temp.alias]](temp.alias "13.7.8 Alias templates"))[.](#atomic-2.sentence-2)

[*Example [1](#atomic-example-1)*: template <unsigned N> constexpr bool Atomic = true;template <unsigned N> concept C = Atomic<N>;template <unsigned N> concept Add1 = C<N + 1>;template <unsigned N> concept AddOne = C<N + 1>;template <unsigned M> void f()requires Add1<2 * M>;template <unsigned M> int f()requires AddOne<2 * M> && true;

int x = f<0>(); // OK, the atomic constraints from concept C in both fs are Atomic<N>// with mapping similar to Nâ¦2 * M + 1template <unsigned N> struct WrapN;template <unsigned N> using Add1Ty = WrapN<N + 1>;template <unsigned N> using AddOneTy = WrapN<N + 1>;template <unsigned M> void g(Add1Ty<2 * M> *);template <unsigned M> void g(AddOneTy<2 * M> *);

void h() { g<0>(nullptr); // OK, there is only one g} â *end example*]

As specified in [[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading"),
if the validity or meaning of the program depends on
whether two constructs are equivalent, and
they are functionally equivalent but not equivalent,
the program is ill-formed, no diagnostic required[.](#atomic-2.sentence-3)

[*Example [2](#atomic-example-2)*: template <unsigned N> void f2()requires Add1<2 * N>;template <unsigned N> int f2()requires Add1<N * 2> && true;void h2() { f2<0>(); // ill-formed, no diagnostic required:// requires determination of subsumption between atomic constraints that are// functionally equivalent but not equivalent} â *end example*]

â *end note*]

[3](#atomic-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1819)

To determine if an atomic constraint is[*satisfied*](#def:constraint,satisfaction,atomic "13.5.2.3 Atomic constraints [temp.constr.atomic]"),
the parameter mapping and template arguments are
first substituted into its expression[.](#atomic-3.sentence-1)

If substitution results in an invalid type or expression
in the immediate context of the atomic constraint ([[temp.deduct.general]](temp.deduct.general "13.10.3.1 General")),
the constraint is not satisfied[.](#atomic-3.sentence-2)

Otherwise, the [lvalue-to-rvalue conversion](conv.lval "7.3.2 Lvalue-to-rvalue conversion [conv.lval]") is performed if necessary,
and E shall be a constant expression of type bool[.](#atomic-3.sentence-3)

The constraint is satisfied if and only if evaluation of E results in true[.](#atomic-3.sentence-4)

If, at different points in the program, the satisfaction result is different
for identical atomic constraints and template arguments,
the program is ill-formed, no diagnostic required[.](#atomic-3.sentence-5)

[*Example [3](#atomic-example-3)*: template<typename T> concept C =sizeof(T) == 4 && !true; // requires atomic constraints sizeof(T) == 4 and !truetemplate<typename T> struct S {constexpr operator bool() const { return true; }};

template<typename T> requires (S<T>{})void f(T); // #1void f(int); // #2void g() { f(0); // error: expression S<int>{} does not have type bool} // while checking satisfaction of deduced arguments of #1;// call is ill-formed even though #2 is a better match â *end example*]

#### [13.5.2.4](#concept) Concept-dependent constraints [[temp.constr.concept]](temp.constr.concept)

[1](#concept-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1857)

A [*concept-dependent constraint*](#def:constraint,concept-dependent "13.5.2.4 Concept-dependent constraints [temp.constr.concept]") CD is
an atomic constraint whose expression is a concept-id CI whose[*concept-name*](temp.concept#nt:concept-name "13.7.9 Concept definitions [temp.concept]") names a dependent concept named C[.](#concept-1.sentence-1)

[2](#concept-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1862)

To determine if CD is[*satisfied*](#def:constraint,satisfaction,concept-dependent "13.5.2.4 Concept-dependent constraints [temp.constr.concept]"),
the parameter mapping and template arguments are first
substituted into C[.](#concept-2.sentence-1)

If substitution results in an invalid concept-id in
the immediate context of the constraint ([[temp.deduct.general]](temp.deduct.general "13.10.3.1 General")),
the constraint is not satisfied[.](#concept-2.sentence-2)

Otherwise, let CIâ² be
the normal form ([[temp.constr.normal]](#normal "13.5.4 Constraint normalization")) of the concept-id
after substitution of C[.](#concept-2.sentence-3)

[*Note [1](#concept-note-1)*:

Normalization of CI might be ill-formed; no diagnostics is required[.](#concept-2.sentence-4)

â *end note*]

[3](#concept-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1877)

To form CIâ²â²,
each appearance of C's template parameters in
the parameter mappings of the atomic constraints
(including concept-dependent constraints)
in CIâ² is substituted with their respective arguments from
the parameter mapping of CD and the arguments of CI[.](#concept-3.sentence-1)

[4](#concept-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1886)

CD is satisfied if CIâ²â² is satisfied[.](#concept-4.sentence-1)

[*Note [2](#concept-note-2)*:

Checking whether CIâ²â² is satisfied
can lead to further normalization of concept-dependent constraints[.](#concept-4.sentence-2)

â *end note*]

[*Example [1](#concept-example-1)*: template<typename>concept C = true;

template<typename T, template<typename> concept CC>concept D = CC<T>;

template<typename U, template<typename> concept CT, template<typename, template<typename> concept> concept CU>int f() requires CU<U, CT>;int i = f<int, C, D>();

In this example, the associated constraints of f consist of a concept-dependent constraint
whose expression is the concept-id CU<U, CT> with the mappingUâ¦U,CTâ¦CT,CUâ¦CU[.](#concept-4.sentence-3)

The result of substituting D into this expression is D<U, CT>[.](#concept-4.sentence-4)

We consider the normal form of the resulting concept-id,
which is CC<T> with the mappingTâ¦U,CCâ¦CT[.](#concept-4.sentence-5)

By recursion, C is substituted into CC<T>, and the result
is normalized to the atomic constraint true, which is satisfied[.](#concept-4.sentence-6)

â *end example*]

#### [13.5.2.5](#fold) Fold expanded constraint [[temp.constr.fold]](temp.constr.fold)

[1](#fold-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1920)

A [*fold expanded constraint*](#def:constraint,fold_expanded "13.5.2.5 Fold expanded constraint [temp.constr.fold]") is formed from a constraint C and
a [*fold-operator*](expr.prim.fold#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") which can either be && or ||[.](#fold-1.sentence-1)

A fold expanded constraint is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#fold-1.sentence-2)

Let N be the number of elements
in the pack expansion parameters ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#fold-1.sentence-3)

[2](#fold-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1928)

A fold expanded constraint whose [*fold-operator*](expr.prim.fold#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") is && is satisfied if it is a valid pack expansion and
if N=0 or if for each i where 0â¤i<N in increasing order,C is satisfied
when replacing each pack expansion parameter
with the corresponding ith element[.](#fold-2.sentence-1)

No substitution takes place for any i greater than
the smallest i for which the constraint is not satisfied[.](#fold-2.sentence-2)

[3](#fold-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1938)

A fold expanded constraint whose [*fold-operator*](expr.prim.fold#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") is || is satisfied if it is a valid pack expansion,N>0, and if for i where 0â¤i<N in increasing order,
there is a smallest i for which C is satisfied
when replacing each pack expansion parameter
with the corresponding ith element[.](#fold-3.sentence-1)

No substitution takes place for any i greater than
the smallest i for which the constraint is satisfied[.](#fold-3.sentence-2)

[4](#fold-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1948)

[*Note [1](#fold-note-1)*:

If the pack expansion expands packs of different size,
then it is invalid and the fold expanded constraint is not satisfied[.](#fold-4.sentence-1)

â *end note*]

[5](#fold-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1954)

Two fold expanded constraints are [*compatible for subsumption*](#def:subsumption,compatible_for "13.5.2.5 Fold expanded constraint [temp.constr.fold]") if their respective constraints both contain
an equivalent unexpanded pack ([[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading"))[.](#fold-5.sentence-1)

### [13.5.3](#decl) Constrained declarations [[temp.constr.decl]](temp.constr.decl)

[1](#decl-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1961)

A template declaration ([[temp.pre]](temp.pre "13.1 Preamble"))
or templated function declaration ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))
can be constrained by the use of a [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")[.](#decl-1.sentence-1)

This allows the specification of constraints for that declaration as
an expression:

[constraint-expression:](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]")  
[*logical-or-expression*](expr.log.or#nt:logical-or-expression "7.6.15 Logical OR operator [expr.log.or]")

[2](#decl-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1972)

Constraints can also be associated with a declaration through the use of[*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]")*s* in a [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") or parameter-type-list[.](#decl-2.sentence-1)

Each of these forms introduces additional [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]")*s* that are used to constrain the declaration[.](#decl-2.sentence-2)

[3](#decl-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L1979)

A declaration's [*associated constraints*](#def:associated_constraints "13.5.3 Constrained declarations [temp.constr.decl]") are defined as follows:

- [(3.1)](#decl-3.1)

  If there are no introduced [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]")*s*,
the declaration has no associated constraints[.](#decl-3.1.sentence-1)

- [(3.2)](#decl-3.2)

  Otherwise, if there is a single introduced [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]"),
the associated constraints are the [normal form](#def:normal_form,constraint "13.5.4 Constraint normalization [temp.constr.normal]") of that expression[.](#decl-3.2.sentence-1)

- [(3.3)](#decl-3.3)

  Otherwise, the associated constraints are the normal form of a [logicaland expression](expr.log.and "7.6.14 Logical AND operator [expr.log.and]") whose operands are in the
following order:
  * [(3.3.1)](#decl-3.3.1)

the [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") introduced by
each [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]") ([[temp.param]](temp.param "13.2 Template parameters")) in
the declaration's [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]"),
in order of appearance, and

  * [(3.3.2)](#decl-3.3.2)

the [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") introduced by
a [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") following
a [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") ([[temp.pre]](temp.pre "13.1 Preamble")), and

  * [(3.3.3)](#decl-3.3.3)

the [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") introduced by
each [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]") in
the parameter-type-list of a function declaration, and

  * [(3.3.4)](#decl-3.3.4)

the [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") introduced by
a trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") ([[dcl.decl]](dcl.decl "9.3 Declarators")) of
a function declaration ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#decl-3.3.sentence-1)

The formation of the associated constraints
establishes the order in which constraints are instantiated when checking
for satisfaction ([[temp.constr.constr]](#constr "13.5.2 Constraints"))[.](#decl-3.sentence-2)

[*Example [1](#decl-example-1)*: 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>;

The functions f1, f2, and f3 have the associated
constraint C<T>[.](#decl-3.sentence-3)

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);

The associated constraints of f4 and f5 are C1<T>  â§  C2<T>[.](#decl-3.sentence-4)

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

The associated constraints off6 are C1<T>  â§  C2<T>,
and those off7 are C2<T>  â§  C1<T>[.](#decl-3.sentence-5)

â *end example*]

[4](#decl-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2051)

When determining whether a given introduced[*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") C1 of a declaration
in an instantiated specialization of a templated class
is equivalent ([[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading")) to the corresponding[*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") C2 of a declaration
outside the class body,C1 is instantiated[.](#decl-4.sentence-1)

If the instantiation results in an invalid expression,
the [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]")*s* are not equivalent[.](#decl-4.sentence-2)

[*Note [1](#decl-note-1)*:

This can happen when determining which member template is specialized
by an explicit specialization declaration[.](#decl-4.sentence-3)

â *end note*]

[*Example [2](#decl-example-2)*: template <class T> concept C = true;template <class T> struct A {template <class U> U f(U) requires C<typename T::type>; // #1template <class U> U f(U) requires C<T>; // #2};

template <> template <class U> U A<int>::f(U u) requires C<int> { 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[.](#decl-4.sentence-4)

Substituting int for T in C<T> produces C<int>,
which is equivalent to the [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") for the specialization,
so it does match #2[.](#decl-4.sentence-5)

â *end example*]

### [13.5.4](#normal) Constraint normalization [[temp.constr.normal]](temp.constr.normal)

[1](#normal-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2085)

The [*normal form*](#def:normal_form,constraint "13.5.4 Constraint normalization [temp.constr.normal]") of an [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") E is
a [constraint](#def:constraint "13.5.2 Constraints [temp.constr.constr]") that is defined as follows:

- [(1.1)](#normal-1.1)

  The normal form of an expression ( E ) is
the normal form of E[.](#normal-1.1.sentence-1)

- [(1.2)](#normal-1.2)

  The normal form of an expression E1 || E2 is
the [disjunction](#def:disjunction "13.5.2.2 Logical operations [temp.constr.op]") of
the normal forms of E1 and E2[.](#normal-1.2.sentence-1)

- [(1.3)](#normal-1.3)

  The normal form of an expression E1 && E2 is the conjunction of
the normal forms of E1 and E2[.](#normal-1.3.sentence-1)

- [(1.4)](#normal-1.4)

  For a concept-id C<A1, A2, …, An> termed CI:
  * [(1.4.1)](#normal-1.4.1)

      If C names a dependent concept,
the normal form of CI is a concept-dependent constraint
whose concept-id is CI and
whose parameter mapping is the identity mapping[.](#normal-1.4.1.sentence-1)

  * [(1.4.2)](#normal-1.4.2)

      Otherwise, to form CE,
any non-dependent concept template argument Ai is substituted into the [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") of C[.](#normal-1.4.2.sentence-1)
      If any such substitution results in an invalid concept-id,
the program is ill-formed; no diagnostic is required[.](#normal-1.4.2.sentence-2)
      The normal form of CI is the result of substituting,
in the normal form N of CE,
appearances of C's template parameters
in the parameter mappings of the atomic constraints in N with their respective arguments from C[.](#normal-1.4.2.sentence-3)
      If any such substitution results in an invalid type or expression,
the program is ill-formed; no diagnostic is required[.](#normal-1.4.2.sentence-4)

  [*Example [1](#normal-example-1)*: template<typename T> concept A = T::value || true;template<typename U> concept B = A<U*>;template<typename V> concept C = B<V&>;
   Normalization of B's [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") is valid and results inT​::​value (with the mapping Tâ¦U*) â¨ true (with an empty mapping),
despite the expression T​::​value being ill-formed
for a pointer type T[.](#normal-1.4.sentence-2)
  Normalization of C's [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") results in the program being ill-formed,
because it would form the invalid type V&* in the parameter mapping[.](#normal-1.4.sentence-3)
 â *end example*]

- [(1.5)](#normal-1.5)

  For a [*fold-operator*](expr.prim.fold#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") Op ([[expr.prim.fold]](expr.prim.fold "7.5.7 Fold expressions"))
that is either && or ||:
  * [(1.5.1)](#normal-1.5.1)

      The normal form of an expression ( ... Op E ) is the normal form of ( E Op ... )[.](#normal-1.5.1.sentence-1)

  * [(1.5.2)](#normal-1.5.2)

      The normal form of an expression ( E1 Op ... Op E2 ) is the normal form of
    +
          [(1.5.2.1)](#normal-1.5.2.1)
( E1 Op ... ) Op E2 if E1 contains an unexpanded pack, or

    +
          [(1.5.2.2)](#normal-1.5.2.2)
E1 Op ( E2 Op ... ) otherwise[.](#normal-1.5.2.sentence-1)

  * [(1.5.3)](#normal-1.5.3)

      The normal form of an expression F of the form ( E Op ... ) is as follows:  
       If E contains an unexpanded concept template parameter pack,
 it shall not contain an unexpanded template parameter pack of another kind[.](#normal-1.5.3.sentence-2)
      Let Eâ² be the normal form of E[.](#normal-1.5.3.sentence-3)

    +
          [(1.5.3.1)](#normal-1.5.3.1)
          If E contains
 an unexpanded concept template parameter pack Pk that
 has corresponding template arguments in
 the parameter mapping of any atomic constraint
 (including concept-dependent constraints) of Eâ²,
 the number of arguments specified for all such Pk shall be the same number N[.](#normal-1.5.3.1.sentence-1)
          The normal form of F is the normal form of E0 Op  Op ENâ1 after substituting in Ei the respective ith concept argument of each Pk[.](#normal-1.5.3.1.sentence-2)
          If any such substitution results in an invalid type or expression,
 the program is ill-formed; no diagnostic is required[.](#normal-1.5.3.1.sentence-3)

    +
          [(1.5.3.2)](#normal-1.5.3.2)
          Otherwise,
 the normal form of F is
 a fold expanded constraint ([[temp.constr.fold]](#fold "13.5.2.5 Fold expanded constraint")) whose
 constraint is Eâ² and whose [*fold-operator*](expr.prim.fold#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") is Op[.](#normal-1.5.3.2.sentence-1)

- [(1.6)](#normal-1.6)

  The normal form of any other expression E is
the atomic constraint
whose expression is E and
whose parameter mapping is the identity mapping[.](#normal-1.6.sentence-1)

[2](#normal-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2201)

The process of obtaining the normal form of a[*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") is called[*normalization*](#def:constraint,normalization "13.5.4 Constraint normalization [temp.constr.normal]")[.](#normal-2.sentence-1)

[*Note [1](#normal-note-1)*:

Normalization of [*constraint-expression*](#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]")*s* is performed
when determining the associated constraints ([[temp.constr.constr]](#constr "13.5.2 Constraints"))
of a declaration
and
when evaluating the value of an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") that names a concept specialization ([[expr.prim.id]](expr.prim.id "7.5.5 Names"))[.](#normal-2.sentence-2)

â *end note*]

[3](#normal-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2217)

[*Example [2](#normal-example-2)*: template<typename T> concept C1 = sizeof(T) == 1;template<typename T> concept C2 = C1<T> && 1 == 2;template<typename T> concept C3 = requires { typename T::type; };template<typename T> concept C4 = requires (T x) { ++x; };

template<C2 U> void f1(U); // #1template<C3 U> void f2(U); // #2template<C4 U> void f3(U); // #3

The associated constraints of #1 aresizeof(T) == 1 (with mapping Tâ¦U)  â§  1 == 2[.](#normal-3.sentence-1)

  


The associated constraints of #2 arerequires { typename T​::​type; } (with mapping Tâ¦U)[.](#normal-3.sentence-2)

  


The associated constraints of #3 arerequires (T x) { ++x; } (with mapping Tâ¦U)[.](#normal-3.sentence-3)

â *end example*]

[*Example [3](#normal-example-3)*: template<typename T>concept C = true;template<typename T, template<typename> concept CT>concept CC = CT<T>;

template<typename U, template<typename, template<typename> concept> concept CT>void f() requires CT<U*, C>;template<typename U>void g() requires CC<U*, C>;

The normal form of the associated constraints of f is
the concept-dependent constraint CT<T, C>[.](#normal-3.sentence-4)

  


The normal form of the associated constraints of g is
the atomic constraint true[.](#normal-3.sentence-5)

â *end example*]

[*Example [4](#normal-example-4)*: template<typename T>concept A = true;template<typename T>concept B = A<T> && true; // B subsumes Atemplate<typename T>concept C = true;template<typename T>concept D = C<T> && true; // D subsumes Ctemplate<typename T, template<typename> concept... CTs>concept all_of = (CTs<T> && ...);

template<typename T> requires all_of<T, A, C>constexpr int f(T) { return 1; } // #1template<typename T> requires all_of<T, B, D>constexpr int f(T) { return 2; } // #2static_assert(f(1) == 2); // ok

The normal form of all_of<T, A, C> is
the conjunction of the normal forms of A<T> and C<T>[.](#normal-3.sentence-6)

  


Similarly, the normal form of all_of<T, B, D> is
the conjunction of the normal forms of B<T> and D<T>[.](#normal-3.sentence-7)

  


#2 therefore is more constrained than #1[.](#normal-3.sentence-8)

â *end example*]

[*Example [5](#normal-example-5)*: template<typename T, template<typename> concept>struct wrapper {};

template<typename... T, template<typename> concept... CTs>int f(wrapper<T, CTs>...) requires (CTs<T> && ...); // error: fold expression contains// different kinds of template parameters â *end example*]

### [13.5.5](#order) Partial ordering by constraints [[temp.constr.order]](temp.constr.order)

[1](#order-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2299)

A constraint P [*subsumes*](#def:constraint,subsumption "13.5.5 Partial ordering by constraints [temp.constr.order]") a constraint Q if and only if,
for every disjunctive clause Pi in the disjunctive normal form[110](#footnote-110 "A constraint is in disjunctive normal form when it is a disjunction of clauses where each clause is a conjunction of fold expanded or atomic constraints. For atomic constraints A, B, and C, the disjunctive normal form of the constraint A  â§ (B  â¨ C) is (A  â§ B)  â¨ (A  â§ C). Its disjunctive clauses are (A  â§ B) and (A  â§ C).") of P, Pi subsumes every conjunctive clause Qj in the conjunctive normal form[111](#footnote-111 "A constraint is in conjunctive normal form when it is a conjunction of clauses where each clause is a disjunction of fold expanded or atomic constraints. For atomic constraints A, B, and C, the constraint A  â§ (B  â¨ C) is in conjunctive normal form. Its conjunctive clauses are A and (B  â¨ C).") of Q, where

- [(1.1)](#order-1.1)

a disjunctive clause Pi subsumes a conjunctive clause Qj if and only
if there exists an atomic constraint Pia in Pi for which there exists
an atomic constraint Qjb in Qj such that Pia subsumes Qjb,

- [(1.2)](#order-1.2)

an atomic constraint A subsumes another atomic constraintB if and only if A and B are identical using the
rules described in [[temp.constr.atomic]](#atomic "13.5.2.3 Atomic constraints"), and

- [(1.3)](#order-1.3)

a fold expanded constraint A subsumes
another fold expanded constraint B if they are compatible for subsumption,
have the same [*fold-operator*](expr.prim.fold#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]"), and
the constraint of A subsumes that of B[.](#order-1.sentence-1)

[*Example [1](#order-example-1)*:

Let A and B be [atomic constraints](#def:constraint,atomic "13.5.2.3 Atomic constraints [temp.constr.atomic]")[.](#order-1.sentence-2)

The constraint A â§ B subsumes A, but A does not subsume A â§ B[.](#order-1.sentence-3)

The constraint A subsumes A â¨ B, but A â¨ B does not subsume A[.](#order-1.sentence-4)

Also note that every constraint subsumes itself[.](#order-1.sentence-5)

â *end example*]

[2](#order-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2354)

[*Note [1](#order-note-1)*:

The subsumption relation defines a partial ordering on constraints[.](#order-2.sentence-1)

This partial ordering is used to determine

- [(2.1)](#order-2.1)

the best viable candidate of non-template functions ([[over.match.best]](over.match.best "12.2.4 Best viable function")),

- [(2.2)](#order-2.2)

the address of a non-template function ([[over.over]](over.over "12.3 Address of an overload set")),

- [(2.3)](#order-2.3)

the matching of template template arguments ([[temp.arg.template]](temp.arg.template "13.4.4 Template template arguments")),

- [(2.4)](#order-2.4)

the partial ordering of class template specializations ([[temp.spec.partial.order]](temp.spec.partial.order "13.7.6.3 Partial ordering of partial specializations")), and

- [(2.5)](#order-2.5)

the partial ordering of function templates ([[temp.func.order]](temp.func.order "13.7.7.3 Partial ordering of function templates"))[.](#order-2.sentence-2)

â *end note*]

[3](#order-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2367)

The associated constraints C of a declaration Dare [*eligible for subsumption*](#def:eligible,for_subsumption "13.5.5 Partial ordering by constraints [temp.constr.order]") unless C contains a concept-dependent constraint[.](#order-3.sentence-1)

[4](#order-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2378)

A declaration D1 is[*at least as constrained*](#def:at_least_as_constrained "13.5.5 Partial ordering by constraints [temp.constr.order]") as
a declaration D2 if

- [(4.1)](#order-4.1)

D1 and D2 are both constrained declarations andD1's associated constraints
are eligible for subsumption and subsume those of D2; or

- [(4.2)](#order-4.2)

D2 has no associated constraints[.](#order-4.sentence-1)

[5](#order-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2390)

A declaration D1 is [*more constrained*](#def:more_constrained "13.5.5 Partial ordering by constraints [temp.constr.order]") than another declaration D2 when D1 is at least as
constrained as D2, and D2 is not at least as
constrained as D1[.](#order-5.sentence-1)

[*Example [2](#order-example-2)*: template<typename T> concept C1 = requires(T t) { --t; };template<typename T> concept C2 = C1<T> && requires(T t) { *t; };

template<C1 T> void f(T); // #1template<C2 T> void f(T); // #2template<typename T> void g(T); // #3template<C1 T> void g(T); // #4 f(0); // selects #1 f((int*)0); // selects #2 g(true); // selects #3 because C1<bool> is not satisfied g(0); // selects #4 â *end example*]

[*Example [3](#order-example-3)*: template<template<typename T> concept CT, typename T>struct S {};template<typename T>concept A = true;

template<template<typename T> concept X, typename T>int f(S<X, T>) requires A<T> { return 42; } // #1template<template<typename T> concept X, typename T>int f(S<X, T>) requires X<T> { return 43; } // #2 f(S<A, int>{}); // ok, select #1 because #2 is not eligible for subsumption â *end example*]

[6](#order-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2427)

A non-template function F1 is [*more partial-ordering-constrained*](#def:more_partial-ordering-constrained "13.5.5 Partial ordering by constraints [temp.constr.order]") than a non-template function F2 if

- [(6.1)](#order-6.1)

they have the same non-object-parameter-type-lists ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")), and

- [(6.2)](#order-6.2)

if they are member functions, both are direct members of the same class, and

- [(6.3)](#order-6.3)

if both are non-static member functions,
they have the same types for their object parameters, and

- [(6.4)](#order-6.4)

the declaration of F1 is more constrained than
the declaration of F2[.](#order-6.sentence-1)

[110)](#footnote-110)[110)](#footnoteref-110)

A constraint is in disjunctive normal form when it is a disjunction of
clauses where each clause is a conjunction of fold expanded or atomic constraints[.](#footnote-110.sentence-1)

For atomic constraints A, B, and C, the disjunctive normal form
of the constraintA â§ (B â¨ C) is(A â§ B) â¨ (A â§ C)[.](#footnote-110.sentence-2)

Its disjunctive clauses are (A â§ B) and (A â§ C)[.](#footnote-110.sentence-3)

[111)](#footnote-111)[111)](#footnoteref-111)

A constraint is in conjunctive normal form when it is a conjunction
of clauses where each clause is a disjunction of fold expanded or atomic constraints[.](#footnote-111.sentence-1)

For atomic constraints A, B, and C, the constraintA â§ (B â¨ C) is in conjunctive normal form[.](#footnote-111.sentence-2)

Its conjunctive clauses are A and (B â¨ C)[.](#footnote-111.sentence-3)
