From Jason Turner

[temp.constr.decl]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpd6rku3uq/{from.md → to.md} +104 -0
tmp/tmpd6rku3uq/{from.md → to.md} RENAMED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Constrained declarations <a id="temp.constr.decl">[[temp.constr.decl]]</a>
2
+
3
+ A template declaration [[temp.pre]] or templated function declaration
4
+ [[dcl.fct]] can be constrained by the use of a *requires-clause*. This
5
+ allows the specification of constraints for that declaration as an
6
+ expression:
7
+
8
+ ``` bnf
9
+ constraint-expression:
10
+ logical-or-expression
11
+ ```
12
+
13
+ Constraints can also be associated with a declaration through the use of
14
+ *type-constraint*s in a *template-parameter-list* or
15
+ parameter-type-list. Each of these forms introduces additional
16
+ *constraint-expression*s that are used to constrain the declaration.
17
+
18
+ A declaration’s *associated constraints* are defined as follows:
19
+
20
+ - If there are no introduced *constraint-expression*s, the declaration
21
+ has no associated constraints.
22
+ - Otherwise, if there is a single introduced *constraint-expression*,
23
+ the associated constraints are the normal form [[temp.constr.normal]]
24
+ of that expression.
25
+ - Otherwise, the associated constraints are the normal form of a logical
26
+ expression [[expr.log.and]] whose operands are in the following order:
27
+ - the *constraint-expression* introduced by each *type-constraint*
28
+ [[temp.param]] in the declaration’s *template-parameter-list*, in
29
+ order of appearance, and
30
+ - the *constraint-expression* introduced by a *requires-clause*
31
+ following a *template-parameter-list* [[temp.pre]], and
32
+ - the *constraint-expression* introduced by each *type-constraint* in
33
+ the parameter-type-list of a function declaration, and
34
+ - the *constraint-expression* introduced by a trailing
35
+ *requires-clause* [[dcl.decl]] of a function declaration
36
+ [[dcl.fct]].
37
+
38
+ The formation of the associated constraints establishes the order in
39
+ which constraints are instantiated when checking for satisfaction
40
+ [[temp.constr.constr]].
41
+
42
+ [*Example 1*:
43
+
44
+ ``` cpp
45
+ template<typename T> concept C = true;
46
+
47
+ template<C T> void f1(T);
48
+ template<typename T> requires C<T> void f2(T);
49
+ template<typename T> void f3(T) requires C<T>;
50
+ ```
51
+
52
+ The functions `f1`, `f2`, and `f3` have the associated constraint
53
+ `C<T>`.
54
+
55
+ ``` cpp
56
+ template<typename T> concept C1 = true;
57
+ template<typename T> concept C2 = sizeof(T) > 0;
58
+
59
+ template<C1 T> void f4(T) requires C2<T>;
60
+ template<typename T> requires C1<T> && C2<T> void f5(T);
61
+ ```
62
+
63
+ The associated constraints of `f4` and `f5` are `C1<T> ∧ C2<T>`.
64
+
65
+ ``` cpp
66
+ template<C1 T> requires C2<T> void f6();
67
+ template<C2 T> requires C1<T> void f7();
68
+ ```
69
+
70
+ The associated constraints of `f6` are `C1<T> ∧ C2<T>`, and those of
71
+ `f7` are `C2<T> ∧ C1<T>`.
72
+
73
+ — *end example*]
74
+
75
+ When determining whether a given introduced *constraint-expression* C₁
76
+ of a declaration in an instantiated specialization of a templated class
77
+ is equivalent [[temp.over.link]] to the corresponding
78
+ *constraint-expression* C₂ of a declaration outside the class body, C₁
79
+ is instantiated. If the instantiation results in an invalid expression,
80
+ the *constraint-expression*s are not equivalent.
81
+
82
+ [*Note 1*: This can happen when determining which member template is
83
+ specialized by an explicit specialization declaration. — *end note*]
84
+
85
+ [*Example 2*:
86
+
87
+ ``` cpp
88
+ template <class T> concept C = true;
89
+ template <class T> struct A {
90
+ template <class U> U f(U) requires C<typename T::type>; // #1
91
+ template <class U> U f(U) requires C<T>; // #2
92
+ };
93
+
94
+ template <> template <class U>
95
+ U A<int>::f(U u) requires C<int> { return u; } // OK, specializes #2
96
+ ```
97
+
98
+ Substituting `int` for `T` in `C<typename T::type>` produces an invalid
99
+ expression, so the specialization does not match \#1. Substituting `int`
100
+ for `T` in `C<T>` produces `C<int>`, which is equivalent to the
101
+ *constraint-expression* for the specialization, so it does match \#2.
102
+
103
+ — *end example*]
104
+