|
130 | 130 | During Core review in Varna, Hubert suggested creating `T[1]` for the array case.
|
131 | 131 | </p>
|
132 | 132 |
|
133 |
| -</discussion> |
134 |
| - |
135 |
| -<resolution> |
| 133 | +<superseded> |
136 | 134 | <p>
|
137 | 135 | This wording is relative to <paper num="N4971"/>.
|
138 | 136 | </p>
|
@@ -169,5 +167,70 @@ else</ins>
|
169 | 167 | </blockquote>
|
170 | 168 | </li>
|
171 | 169 | </ol>
|
| 170 | +</superseded> |
| 171 | + |
| 172 | +<note>St. Louis 2024-06-24; Jonathan provides improved wording</note> |
| 173 | +<p> |
| 174 | +Why not support unbounded arrays, deducing the bound from `sizeof...(Args)`? |
| 175 | +<br/> |
| 176 | +JW: There's no motivation to support that here in `construct_at`. |
| 177 | +It isn't possible to create unbounded arrays via allocators, |
| 178 | +nor via any of the `uninitialized_xxx` algorithms. Extending `construct_at` |
| 179 | +that way seems like a design change, not restoring support for something |
| 180 | +that used to work with allocators and then got broken in C++20. |
| 181 | +</p> |
| 182 | +<p> |
| 183 | +Tim observed that the proposed resolution is ill-formed if `T` has an |
| 184 | +explicit default constructor. Value-initialization would work for that case, |
| 185 | +and there seems to be little motivation for supplying arguments to |
| 186 | +initialize the array. In C++17 the `allocator_traits::construct` case only |
| 187 | +supported value-initialization. |
| 188 | +</p> |
| 189 | + |
| 190 | +</discussion> |
| 191 | + |
| 192 | +<resolution> |
| 193 | +<p> |
| 194 | +This wording is relative to <paper num="N4981"/>. |
| 195 | +</p> |
| 196 | + |
| 197 | +<ol> |
| 198 | +<li><p>Modify <sref ref="[specialized.construct]"/> as indicated:</p> |
| 199 | + |
| 200 | +<blockquote> |
| 201 | +<pre> |
| 202 | +template<class T, class... Args> |
| 203 | + constexpr T* construct_at(T* location, Args&&... args); |
| 204 | + |
| 205 | +namespace ranges { |
| 206 | + template<class T, class... Args> |
| 207 | + constexpr T* construct_at(T* location, Args&&... args); |
| 208 | +} |
| 209 | +</pre> |
| 210 | +<blockquote> |
| 211 | +<p> |
| 212 | +-1- <i>Constraints:</i> |
| 213 | +<ins><tt>is_unbounded_array_v<T></tt> is <tt>false</tt>.</ins> |
| 214 | +The expression <tt>::new (declval<void*>()) T(declval<Args>()...)</tt> is well-formed |
| 215 | +when treated as an unevaluated operand (<sref ref="[expr.context]"/>). |
| 216 | +</p> |
| 217 | +<p> |
| 218 | +<ins>-?- <i>Mandates</i>: |
| 219 | +If <code>is_array_v<T></code> is `true`, `sizeof...(Args)` is zero. |
| 220 | +</ins> |
| 221 | +</p> |
| 222 | +<p> |
| 223 | +-2- <i>Effects:</i> Equivalent to: |
| 224 | +</p> |
| 225 | +<blockquote><pre> |
| 226 | +<ins>if constexpr (is_array_v<T>) |
| 227 | + return ::new (<i>voidify</i>(*location)) T[1](); |
| 228 | +else</ins> |
| 229 | + return ::new (<i>voidify</i>(*location)) T(std::forward<Args>(args)...); |
| 230 | +</pre></blockquote> |
| 231 | +</blockquote> |
| 232 | +</blockquote> |
| 233 | +</li> |
| 234 | +</ol> |
172 | 235 | </resolution>
|
173 | 236 | </issue>
|
0 commit comments