tmp/tmprmsze9fj/{from.md → to.md}
RENAMED
|
@@ -18,58 +18,52 @@ specifier. — *end note*]
|
|
| 18 |
`constexpr`. — *end note*]
|
| 19 |
|
| 20 |
[*Example 1*:
|
| 21 |
|
| 22 |
``` cpp
|
| 23 |
-
constexpr void square(int &x); // OK
|
| 24 |
-
constexpr int bufsz = 1024; // OK
|
| 25 |
constexpr struct pixel { // error: pixel is a type
|
| 26 |
int x;
|
| 27 |
int y;
|
| 28 |
-
constexpr pixel(int); // OK
|
| 29 |
};
|
| 30 |
constexpr pixel::pixel(int a)
|
| 31 |
-
: x(a), y(x) // OK
|
| 32 |
{ square(x); }
|
| 33 |
constexpr pixel small(2); // error: square not defined, so small(2)
|
| 34 |
// not constant[expr.const] so constexpr not satisfied
|
| 35 |
|
| 36 |
-
constexpr void square(int &x) { // OK
|
| 37 |
x *= x;
|
| 38 |
}
|
| 39 |
-
constexpr pixel large(4); // OK
|
| 40 |
int next(constexpr int x) { // error: not for parameters
|
| 41 |
return x + 1;
|
| 42 |
}
|
| 43 |
extern constexpr int memsz; // error: not a definition
|
| 44 |
```
|
| 45 |
|
| 46 |
— *end example*]
|
| 47 |
|
| 48 |
A `constexpr` or `consteval` specifier used in the declaration of a
|
| 49 |
-
function declares that function to be a *constexpr function*.
|
| 50 |
-
or constructor declared with the `consteval` specifier is called an
|
| 51 |
-
*immediate function*. A destructor, an allocation function, or a
|
| 52 |
-
deallocation function shall not be declared with the `consteval`
|
| 53 |
-
specifier.
|
| 54 |
|
| 55 |
-
|
| 56 |
-
|
| 57 |
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
- it shall not be a coroutine [[dcl.fct.def.coroutine]];
|
| 61 |
-
- if the function is a constructor or destructor, its class shall not
|
| 62 |
-
have any virtual base classes;
|
| 63 |
-
- its *function-body* shall not enclose [[stmt.pre]]
|
| 64 |
-
- a `goto` statement,
|
| 65 |
-
- an identifier label [[stmt.label]],
|
| 66 |
-
- a definition of a variable of non-literal type or of static or
|
| 67 |
-
thread storage duration.
|
| 68 |
|
| 69 |
-
|
| 70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
|
| 72 |
[*Example 2*:
|
| 73 |
|
| 74 |
``` cpp
|
| 75 |
constexpr int square(int x)
|
|
@@ -79,14 +73,17 @@ constexpr long long_max()
|
|
| 79 |
constexpr int abs(int x) {
|
| 80 |
if (x < 0)
|
| 81 |
x = -x;
|
| 82 |
return x; // OK
|
| 83 |
}
|
| 84 |
-
constexpr int
|
| 85 |
-
|
|
|
|
| 86 |
return value;
|
| 87 |
}
|
|
|
|
|
|
|
| 88 |
constexpr int uninit() {
|
| 89 |
struct { int a; } s;
|
| 90 |
return s.a; // error: uninitialized read of s.a
|
| 91 |
}
|
| 92 |
constexpr int prev(int x)
|
|
@@ -98,77 +95,10 @@ constexpr int g(int x, int n) { // OK
|
|
| 98 |
}
|
| 99 |
```
|
| 100 |
|
| 101 |
— *end example*]
|
| 102 |
|
| 103 |
-
The definition of a constexpr constructor whose *function-body* is not
|
| 104 |
-
`= delete` shall additionally satisfy the following requirements:
|
| 105 |
-
|
| 106 |
-
- for a non-delegating constructor, every constructor selected to
|
| 107 |
-
initialize non-static data members and base class subobjects shall be
|
| 108 |
-
a constexpr constructor;
|
| 109 |
-
- for a delegating constructor, the target constructor shall be a
|
| 110 |
-
constexpr constructor.
|
| 111 |
-
|
| 112 |
-
[*Example 3*:
|
| 113 |
-
|
| 114 |
-
``` cpp
|
| 115 |
-
struct Length {
|
| 116 |
-
constexpr explicit Length(int i = 0) : val(i) { }
|
| 117 |
-
private:
|
| 118 |
-
int val;
|
| 119 |
-
};
|
| 120 |
-
```
|
| 121 |
-
|
| 122 |
-
— *end example*]
|
| 123 |
-
|
| 124 |
-
The definition of a constexpr destructor whose *function-body* is not
|
| 125 |
-
`= delete` shall additionally satisfy the following requirement:
|
| 126 |
-
|
| 127 |
-
- for every subobject of class type or (possibly multi-dimensional)
|
| 128 |
-
array thereof, that class type shall have a constexpr destructor.
|
| 129 |
-
|
| 130 |
-
For a constexpr function or constexpr constructor that is neither
|
| 131 |
-
defaulted nor a template, if no argument values exist such that an
|
| 132 |
-
invocation of the function or constructor could be an evaluated
|
| 133 |
-
subexpression of a core constant expression [[expr.const]], or, for a
|
| 134 |
-
constructor, an evaluated subexpression of the initialization
|
| 135 |
-
full-expression of some constant-initialized object
|
| 136 |
-
[[basic.start.static]], the program is ill-formed, no diagnostic
|
| 137 |
-
required.
|
| 138 |
-
|
| 139 |
-
[*Example 4*:
|
| 140 |
-
|
| 141 |
-
``` cpp
|
| 142 |
-
constexpr int f(bool b)
|
| 143 |
-
{ return b ? throw 0 : 0; } // OK
|
| 144 |
-
constexpr int f() { return f(true); } // ill-formed, no diagnostic required
|
| 145 |
-
|
| 146 |
-
struct B {
|
| 147 |
-
constexpr B(int x) : i(0) { } // x is unused
|
| 148 |
-
int i;
|
| 149 |
-
};
|
| 150 |
-
|
| 151 |
-
int global;
|
| 152 |
-
|
| 153 |
-
struct D : B {
|
| 154 |
-
constexpr D() : B(global) { } // ill-formed, no diagnostic required
|
| 155 |
-
// lvalue-to-rvalue conversion on non-constant global
|
| 156 |
-
};
|
| 157 |
-
```
|
| 158 |
-
|
| 159 |
-
— *end example*]
|
| 160 |
-
|
| 161 |
-
If the instantiated template specialization of a constexpr function
|
| 162 |
-
template or member function of a class template would fail to satisfy
|
| 163 |
-
the requirements for a constexpr function, that specialization is still
|
| 164 |
-
a constexpr function, even though a call to such a function cannot
|
| 165 |
-
appear in a constant expression. If no specialization of the template
|
| 166 |
-
would satisfy the requirements for a constexpr function when considered
|
| 167 |
-
as a non-template function, the template is ill-formed, no diagnostic
|
| 168 |
-
required.
|
| 169 |
-
|
| 170 |
An invocation of a constexpr function in a given context produces the
|
| 171 |
same result as an invocation of an equivalent non-constexpr function in
|
| 172 |
the same context in all respects except that
|
| 173 |
|
| 174 |
- an invocation of a constexpr function can appear in a constant
|
|
@@ -179,14 +109,18 @@ the same context in all respects except that
|
|
| 179 |
[*Note 4*: Declaring a function constexpr can change whether an
|
| 180 |
expression is a constant expression. This can indirectly cause calls to
|
| 181 |
`std::is_constant_evaluated` within an invocation of the function to
|
| 182 |
produce a different value. — *end note*]
|
| 183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
The `constexpr` and `consteval` specifiers have no effect on the type of
|
| 185 |
a constexpr function.
|
| 186 |
|
| 187 |
-
[*Example
|
| 188 |
|
| 189 |
``` cpp
|
| 190 |
constexpr int bar(int x, int y) // OK
|
| 191 |
{ return x + y + x*y; }
|
| 192 |
// ...
|
|
@@ -198,13 +132,15 @@ int bar(int x, int y) // error: redefinition of bar
|
|
| 198 |
|
| 199 |
A `constexpr` specifier used in an object declaration declares the
|
| 200 |
object as const. Such an object shall have literal type and shall be
|
| 201 |
initialized. In any `constexpr` variable declaration, the
|
| 202 |
full-expression of the initialization shall be a constant expression
|
| 203 |
-
[[expr.const]]. A `constexpr` variable
|
|
|
|
|
|
|
| 204 |
|
| 205 |
-
[*Example
|
| 206 |
|
| 207 |
``` cpp
|
| 208 |
struct pixel {
|
| 209 |
int x, y;
|
| 210 |
};
|
|
|
|
| 18 |
`constexpr`. — *end note*]
|
| 19 |
|
| 20 |
[*Example 1*:
|
| 21 |
|
| 22 |
``` cpp
|
| 23 |
+
constexpr void square(int &x); // OK, declaration
|
| 24 |
+
constexpr int bufsz = 1024; // OK, definition
|
| 25 |
constexpr struct pixel { // error: pixel is a type
|
| 26 |
int x;
|
| 27 |
int y;
|
| 28 |
+
constexpr pixel(int); // OK, declaration
|
| 29 |
};
|
| 30 |
constexpr pixel::pixel(int a)
|
| 31 |
+
: x(a), y(x) // OK, definition
|
| 32 |
{ square(x); }
|
| 33 |
constexpr pixel small(2); // error: square not defined, so small(2)
|
| 34 |
// not constant[expr.const] so constexpr not satisfied
|
| 35 |
|
| 36 |
+
constexpr void square(int &x) { // OK, definition
|
| 37 |
x *= x;
|
| 38 |
}
|
| 39 |
+
constexpr pixel large(4); // OK, square defined
|
| 40 |
int next(constexpr int x) { // error: not for parameters
|
| 41 |
return x + 1;
|
| 42 |
}
|
| 43 |
extern constexpr int memsz; // error: not a definition
|
| 44 |
```
|
| 45 |
|
| 46 |
— *end example*]
|
| 47 |
|
| 48 |
A `constexpr` or `consteval` specifier used in the declaration of a
|
| 49 |
+
function declares that function to be a *constexpr function*.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
+
[*Note 3*: A function or constructor declared with the `consteval`
|
| 52 |
+
specifier is an immediate function [[expr.const]]. — *end note*]
|
| 53 |
|
| 54 |
+
A destructor, an allocation function, or a deallocation function shall
|
| 55 |
+
not be declared with the `consteval` specifier.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
+
A function is *constexpr-suitable* if:
|
| 58 |
+
|
| 59 |
+
- it is not a coroutine [[dcl.fct.def.coroutine]], and
|
| 60 |
+
- if the function is a constructor or destructor, its class does not
|
| 61 |
+
have any virtual base classes.
|
| 62 |
+
|
| 63 |
+
Except for instantiated constexpr functions, non-templated constexpr
|
| 64 |
+
functions shall be constexpr-suitable.
|
| 65 |
|
| 66 |
[*Example 2*:
|
| 67 |
|
| 68 |
``` cpp
|
| 69 |
constexpr int square(int x)
|
|
|
|
| 73 |
constexpr int abs(int x) {
|
| 74 |
if (x < 0)
|
| 75 |
x = -x;
|
| 76 |
return x; // OK
|
| 77 |
}
|
| 78 |
+
constexpr int constant_non_42(int n) { // OK
|
| 79 |
+
if (n == 42) {
|
| 80 |
+
static int value = n;
|
| 81 |
return value;
|
| 82 |
}
|
| 83 |
+
return n;
|
| 84 |
+
}
|
| 85 |
constexpr int uninit() {
|
| 86 |
struct { int a; } s;
|
| 87 |
return s.a; // error: uninitialized read of s.a
|
| 88 |
}
|
| 89 |
constexpr int prev(int x)
|
|
|
|
| 95 |
}
|
| 96 |
```
|
| 97 |
|
| 98 |
— *end example*]
|
| 99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
An invocation of a constexpr function in a given context produces the
|
| 101 |
same result as an invocation of an equivalent non-constexpr function in
|
| 102 |
the same context in all respects except that
|
| 103 |
|
| 104 |
- an invocation of a constexpr function can appear in a constant
|
|
|
|
| 109 |
[*Note 4*: Declaring a function constexpr can change whether an
|
| 110 |
expression is a constant expression. This can indirectly cause calls to
|
| 111 |
`std::is_constant_evaluated` within an invocation of the function to
|
| 112 |
produce a different value. — *end note*]
|
| 113 |
|
| 114 |
+
[*Note 5*: It is possible to write a constexpr function for which no
|
| 115 |
+
invocation satisfies the requirements of a core constant
|
| 116 |
+
expression. — *end note*]
|
| 117 |
+
|
| 118 |
The `constexpr` and `consteval` specifiers have no effect on the type of
|
| 119 |
a constexpr function.
|
| 120 |
|
| 121 |
+
[*Example 3*:
|
| 122 |
|
| 123 |
``` cpp
|
| 124 |
constexpr int bar(int x, int y) // OK
|
| 125 |
{ return x + y + x*y; }
|
| 126 |
// ...
|
|
|
|
| 132 |
|
| 133 |
A `constexpr` specifier used in an object declaration declares the
|
| 134 |
object as const. Such an object shall have literal type and shall be
|
| 135 |
initialized. In any `constexpr` variable declaration, the
|
| 136 |
full-expression of the initialization shall be a constant expression
|
| 137 |
+
[[expr.const]]. A `constexpr` variable that is an object, as well as any
|
| 138 |
+
temporary to which a `constexpr` reference is bound, shall have constant
|
| 139 |
+
destruction.
|
| 140 |
|
| 141 |
+
[*Example 4*:
|
| 142 |
|
| 143 |
``` cpp
|
| 144 |
struct pixel {
|
| 145 |
int x, y;
|
| 146 |
};
|