[temp.constr.decl] # 13 Templates [[temp]](./#temp) ## 13.5 Template constraints [[temp.constr]](temp.constr#decl) ### 13.5.3 Constrained declarations [temp.constr.decl] [1](#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]")[.](#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](#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[.](#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[.](#2.sentence-2) [3](#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)](#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[.](#3.1.sentence-1) - [(3.2)](#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](temp.constr.normal#def:normal_form,constraint "13.5.4 Constraint normalization [temp.constr.normal]") of that expression[.](#3.2.sentence-1) - [(3.3)](#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)](#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)](#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)](#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)](#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"))[.](#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]](temp.constr.constr "13.5.2 Constraints"))[.](#3.sentence-2) [*Example [1](#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[.](#3.sentence-3) 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[.](#3.sentence-4) template requires C2 void f6();template requires C1 void f7(); The associated constraints off6 are C1 ∧ C2, and those off7 are C2 ∧ C1[.](#3.sentence-5) — *end example*] [4](#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[.](#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[.](#4.sentence-2) [*Note [1](#note-1)*: This can happen when determining which member template is specialized by an explicit specialization declaration[.](#4.sentence-3) — *end note*] [*Example [2](#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 produces an invalid expression, so the specialization does not match #1[.](#4.sentence-4) Substituting int for T in C produces C, 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[.](#4.sentence-5) — *end example*]