Skip to content

Commit 0df1cc6

Browse files
committed
New P/R for 3436
1 parent c9cc53d commit 0df1cc6

File tree

1 file changed

+66
-3
lines changed

1 file changed

+66
-3
lines changed

xml/issue3436.xml

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,7 @@ else
130130
During Core review in Varna, Hubert suggested creating `T[1]` for the array case.
131131
</p>
132132

133-
</discussion>
134-
135-
<resolution>
133+
<superseded>
136134
<p>
137135
This wording is relative to <paper num="N4971"/>.
138136
</p>
@@ -169,5 +167,70 @@ else</ins>
169167
</blockquote>
170168
</li>
171169
</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&lt;class T, class... Args&gt;
203+
constexpr T* construct_at(T* location, Args&amp;&amp;... args);
204+
205+
namespace ranges {
206+
template&lt;class T, class... Args&gt;
207+
constexpr T* construct_at(T* location, Args&amp;&amp;... args);
208+
}
209+
</pre>
210+
<blockquote>
211+
<p>
212+
-1- <i>Constraints:</i>
213+
<ins><tt>is_unbounded_array_v&lt;T&gt;</tt> is <tt>false</tt>.</ins>
214+
The expression <tt>::new (declval&lt;void*&gt;()) T(declval&lt;Args&gt;()...)</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&lt;T&gt;</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&lt;T&gt;)
227+
return ::new (<i>voidify</i>(*location)) T[1]();
228+
else</ins>
229+
return ::new (<i>voidify</i>(*location)) T(std::forward&lt;Args&gt;(args)...);
230+
</pre></blockquote>
231+
</blockquote>
232+
</blockquote>
233+
</li>
234+
</ol>
172235
</resolution>
173236
</issue>

0 commit comments

Comments
 (0)