130 lines
6.7 KiB
Markdown
130 lines
6.7 KiB
Markdown
[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<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>[.](#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>[.](#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>[.](#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 <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[.](#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[.](#4.sentence-5)
|
||
|
||
â *end example*]
|