Skip to content

Commit 60ef45c

Browse files
committed
New issue from Jonathan B. Coe: "Constraints on incomplete types in indirect and polymorphic"
1 parent 43fe0e6 commit 60ef45c

File tree

1 file changed

+298
-0
lines changed

1 file changed

+298
-0
lines changed

xml/issue4322.xml

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4322" status="New">
5+
<title>Constraints on incomplete types in indirect and polymorphic</title>
6+
<section>
7+
<sref ref="[mem.composite.types]"/>
8+
</section>
9+
<submitter>Jonathan B. Coe</submitter>
10+
<date>20 Aug 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
The class templates <tt>indirect&lt;T&gt;</tt> and <tt>polymorphic&lt;T&gt;</tt> allow the template argument `T`
16+
to be an incomplete type.
17+
<p/>
18+
Both classes can be instantiated when the type `T` is incomplete: constraints are written so that requirements
19+
on incomplete types are not evaluated at class instantiation time.
20+
<p/>
21+
For constructors with additional template parameters, there are currently constraints written on the potentially
22+
incomplete type `T` and the additional template parameters. Such constraints will not be evaluated at class
23+
instantiation time but could be explicitly evaluated in contexts where support for an incomplete `T` is required.
24+
</p>
25+
<blockquote><pre>
26+
template&lt;typename U&gt;
27+
class A {
28+
U u;
29+
public:
30+
A(const <i>SomeType</i>&amp;) requires std::is_constructible_v&lt;U, <i>SomeType</i>&gt;
31+
{
32+
// [&hellip;]
33+
}
34+
};
35+
</pre></blockquote>
36+
<p>
37+
when `U` is <tt>indirect&lt;T&gt;</tt> or <tt>polymorphic&lt;T&gt;</tt> for some type `T`, the existence
38+
of the requires clause will require that `T` is a complete type for constraints on indirect or polymorphic
39+
to be evaluated.
40+
<p/>
41+
<i>Constraints</i> on `T` should be converted to <i>Mandates</i> on `T` so that constraint evaluation
42+
does not require `T` to be a complete type.
43+
</p>
44+
</discussion>
45+
46+
<resolution>
47+
<p>
48+
This wording is relative to <paper num="N5014"/>.
49+
</p>
50+
51+
<ol>
52+
53+
<li><p>Modify <sref ref="[indirect.ctor]"/> as indicated:</p>
54+
55+
<blockquote>
56+
<pre>
57+
template&lt;class U = T&gt;
58+
constexpr explicit indirect(U&amp;&amp; u);
59+
</pre>
60+
<blockquote>
61+
<p>
62+
-17- <i>Constraints</i>:
63+
</p>
64+
<ol style="list-style-type: none">
65+
<li><p>(17.1) &mdash; <tt>is_same_v&lt;remove_cvref_t&lt;U&gt;, indirect&gt;</tt> is `false`,</p></li>
66+
<li><p>(17.2) &mdash; <tt>is_same_v&lt;remove_cvref_t&lt;U&gt;, in_place_t&gt;</tt> is `false`, <ins>and</ins></p></li>
67+
<li><p><del>(17.3) &mdash; <tt>is_constructible_v&lt;T, U&gt;</tt> is `true`, and</del></p></li>
68+
<li><p>(17.4) &mdash; <tt>is_default_constructible_v&lt;Allocator&gt;</tt> is `true`.</p></li>
69+
</ol>
70+
<p>
71+
<ins>-?- <i>Mandates:</i> <tt>is_constructible_v&lt;T, U&gt;</tt> is `true`.</ins>
72+
<p/>
73+
-18- <i>Effects</i>: [&hellip;]
74+
</p>
75+
</blockquote>
76+
<pre>
77+
template&lt;class U = T&gt;
78+
constexpr explicit indirect(allocator_arg_t, const Allocator&amp; a, U&amp;&amp; u);
79+
</pre>
80+
<blockquote>
81+
<p>
82+
-19- <i>Constraints</i>:
83+
</p>
84+
<ol style="list-style-type: none">
85+
<li><p>(19.1) &mdash; <tt>is_same_v&lt;remove_cvref_t&lt;U&gt;, indirect&gt;</tt> is `false`, <ins>and</ins></p></li>
86+
<li><p>(19.2) &mdash; <tt>is_same_v&lt;remove_cvref_t&lt;U&gt;, in_place_t&gt;</tt> is `false`<ins>.</ins><del>, and</del></p></li>
87+
<li><p><del>(19.3) &mdash; <tt>is_constructible_v&lt;T, U&gt;</tt> is `true`</del></p></li>
88+
</ol>
89+
<p>
90+
<ins>-?- <i>Mandates:</i> <tt>is_constructible_v&lt;T, U&gt;</tt> is `true`.</ins>
91+
<p/>
92+
-20- <i>Effects</i>: [&hellip;]
93+
</p>
94+
</blockquote>
95+
<pre>
96+
template&lt;class... Us&gt;
97+
constexpr explicit indirect(in_place_t, Us&amp;&amp;... us);
98+
</pre>
99+
<blockquote>
100+
<p>
101+
-21- <i>Constraints</i>:
102+
</p>
103+
<ol style="list-style-type: none">
104+
<li><p><del>(21.1) &mdash; <tt>is_constructible_v&lt;T, Us...&gt;</tt> is `true`, and</del></p></li>
105+
<li><p><del>(21.2) &mdash;</del> <tt>is_default_constructible_v&lt;Allocator&gt;</tt> is `true`.</p></li>
106+
</ol>
107+
<p>
108+
<ins>-?- <i>Mandates:</i> <tt>is_constructible_v&lt;T, Us...&gt;</tt> is `true`.</ins>
109+
<p/>
110+
-22- <i>Effects</i>: [&hellip;]
111+
</p>
112+
</blockquote>
113+
<pre>
114+
template&lt;class... Us&gt;
115+
constexpr explicit indirect(allocator_arg_t, const Allocator&amp; a,
116+
in_place_t, Us&amp;&amp; ...us);
117+
</pre>
118+
<blockquote>
119+
<p>
120+
-23- <i><del>Constraints</del><ins>Mandates</ins></i>: <tt>is_constructible_v&lt;T, Us...&gt;</tt> is `true`
121+
<p/>
122+
-24- <i>Effects</i>: [&hellip;]
123+
</p>
124+
</blockquote>
125+
<pre>
126+
template&lt;class I, class... Us&gt;
127+
constexpr explicit indirect(in_place_t, initializer_list&lt;I&gt; ilist, Us&amp;&amp;... us);
128+
</pre>
129+
<blockquote>
130+
<p>
131+
-25- <i>Constraints</i>:
132+
</p>
133+
<ol style="list-style-type: none">
134+
<li><p><del>(25.1) &mdash; <tt>is_constructible_v&lt;T, initializer_list&lt;I&gt;&amp;, Us...&gt;</tt> is `true`, and</del></p></li>
135+
<li><p><del>(25.2) &mdash;</del> <tt>is_default_constructible_v&lt;Allocator&gt;</tt> is `true`.</p></li>
136+
</ol>
137+
<p>
138+
<ins>-?- <i>Mandates:</i> <tt>is_constructible_v&lt;T, initializer_list&lt;I&gt;&amp;, Us...&gt;</tt> is `true`.</ins>
139+
<p/>
140+
<p/>
141+
-26- <i>Effects</i>: [&hellip;]
142+
</p>
143+
</blockquote>
144+
<pre>
145+
template&lt;class I, class... Us&gt;
146+
constexpr explicit indirect(allocator_arg_t, const Allocator&amp; a,
147+
in_place_t, initializer_list&lt;I&gt; ilist, Us&amp;&amp;... us);
148+
</pre>
149+
<blockquote>
150+
<p>
151+
-27- <i><del>Constraints</del><ins>Mandates</ins></i>: <tt>is_constructible_v&lt;T, initializer_list&lt;I&gt;&amp;, Us...&gt;</tt>
152+
is `true`
153+
<p/>
154+
-28- <i>Effects</i>: [&hellip;]
155+
</p>
156+
</blockquote>
157+
158+
</blockquote>
159+
160+
</li>
161+
162+
<li><p>Modify <sref ref="[polymorphic.ctor]"/> as indicated:</p>
163+
164+
<blockquote>
165+
<pre>
166+
template&lt;class U = T&gt;
167+
constexpr explicit polymorphic(U&amp;&amp; u);
168+
</pre>
169+
<blockquote>
170+
<p>
171+
-12- <i>Constraints</i>: Where `UU` is <tt>remove_cvref_t&lt;U&gt;</tt>,
172+
</p>
173+
<ol style="list-style-type: none">
174+
<li><p>(12.1) &mdash; <tt>is_same_v&lt;UU, polymorphic&gt;</tt> is `false`,</p></li>
175+
<li><p><del>(12.2) &mdash; <tt>derived_from&lt;UU, T&gt;</tt> is `true`,</del></p></li>
176+
<li><p>(12.3) &mdash; <tt>is_constructible_v&lt;UU, U&gt;</tt> is `true`,</p></li>
177+
<li><p>(12.4) &mdash; <tt>is_copy_constructible_v&lt;UU&gt;</tt> is `true`,</p></li>
178+
<li><p>(12.5) &mdash; `UU` is not a specialization of `in_place_type_t`, and</p></li>
179+
<li><p>(12.6) &mdash; <tt>is_default_constructible_v&lt;Allocator&gt;</tt> is `true`.</p></li>
180+
</ol>
181+
<p>
182+
<ins>-?- <i>Mandates:</i> <tt>derived_from&lt;UU, T&gt;</tt> is `true`.</ins>
183+
<p/>
184+
-13- <i>Effects</i>: [&hellip;]
185+
</p>
186+
</blockquote>
187+
<pre>
188+
template&lt;class U = T&gt;
189+
constexpr explicit polymorphic(allocator_arg_t, const Allocator&amp; a, U&amp;&amp; u);
190+
</pre>
191+
<blockquote>
192+
<p>
193+
-14- <i>Constraints</i>: Where `UU` is <tt>remove_cvref_t&lt;U&gt;</tt>,
194+
</p>
195+
<ol style="list-style-type: none">
196+
<li><p>(14.1) &mdash; <tt>is_same_v&lt;UU, polymorphic&gt;</tt> is `false`,</p></li>
197+
<li><p><del>(14.2) &mdash; <tt>derived_from&lt;UU, T&gt;</tt> is `true`,</del></p></li>
198+
<li><p>(14.3) &mdash; <tt>is_constructible_v&lt;UU, U&gt;</tt> is `true`,</p></li>
199+
<li><p>(14.4) &mdash; <tt>is_copy_constructible_v&lt;UU&gt;</tt> is `true`, and</p></li>
200+
<li><p>(14.5) &mdash; `UU` is not a specialization of `in_place_type_t`.</p></li>
201+
</ol>
202+
<p>
203+
<ins>-?- <i>Mandates:</i> <tt>derived_from&lt;UU, T&gt;</tt> is `true`.</ins>
204+
<p/>
205+
-15- <i>Effects</i>: [&hellip;]
206+
</p>
207+
</blockquote>
208+
<pre>
209+
template&lt;class U, class... Ts&gt;
210+
constexpr explicit polymorphic(in_place_type_t&lt;U&gt;, Ts&amp;&amp;... ts);
211+
</pre>
212+
<blockquote>
213+
<p>
214+
-16- <i>Constraints</i>:
215+
</p>
216+
<ol style="list-style-type: none">
217+
<li><p>(16.1) &mdash; <tt>is_same_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</tt> is `true`,</p></li>
218+
<li><p><del>(16.2) &mdash; <tt>derived_from&lt;U, T&gt;</tt> is `true`,</del></p></li>
219+
<li><p>(16.3) &mdash; <tt>is_constructible_v&lt;U, Ts&gt;</tt> is `true`,</p></li>
220+
<li><p>(16.4) &mdash; <tt>is_copy_constructible_v&lt;U&gt;</tt> is `true`, and</p></li>
221+
<li><p>(16.5) &mdash; <tt>is_default_constructible_v&lt;Allocator&gt;</tt> is `true`.</p></li>
222+
</ol>
223+
<p>
224+
<ins>-?- <i>Mandates:</i> <tt>derived_from&lt;U, T&gt;</tt> is `true`.</ins>
225+
<p/>
226+
-17- <i>Effects</i>: [&hellip;]
227+
</p>
228+
</blockquote>
229+
<pre>
230+
template&lt;class U, class... Ts&gt;
231+
constexpr explicit polymorphic(allocator_arg_t, const Allocator&amp; a,
232+
in_place_type_t&lt;U&gt;, Ts&amp;&amp;... ts);
233+
</pre>
234+
<blockquote>
235+
<p>
236+
-18- <i>Constraints</i>:
237+
</p>
238+
<ol style="list-style-type: none">
239+
<li><p>(18.1) &mdash; <tt>is_same_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</tt> is `true`,</p></li>
240+
<li><p><del>(18.2) &mdash; <tt>derived_from&lt;U, T&gt;</tt> is `true`,</del></p></li>
241+
<li><p>(18.3) &mdash; <tt>is_constructible_v&lt;U, Ts&gt;</tt> is `true`, and</p></li>
242+
<li><p>(18.4) &mdash; <tt>is_copy_constructible_v&lt;U&gt;</tt> is `true`.</p></li>
243+
</ol>
244+
<p>
245+
<ins>-?- <i>Mandates:</i> <tt>derived_from&lt;U, T&gt;</tt> is `true`.</ins>
246+
<p/>
247+
-19- <i>Effects</i>: [&hellip;]
248+
</p>
249+
</blockquote>
250+
<pre>
251+
template&lt;class U, class I, class... Us&gt;
252+
constexpr explicit polymorphic(in_place_type_t&lt;U&gt;, initializer_list&lt;I&gt; ilist, Us&amp;&amp;... us);
253+
</pre>
254+
<blockquote>
255+
<p>
256+
-20- <i>Constraints</i>:
257+
</p>
258+
<ol style="list-style-type: none">
259+
<li><p>(20.1) &mdash; <tt>is_same_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</tt> is `true`,</p></li>
260+
<li><p><del>(20.2) &mdash; <tt>derived_from&lt;U, T&gt;</tt> is `true`,</del></p></li>
261+
<li><p>(20.3) &mdash; <tt>is_constructible_v&lt;U, initializer_list&lt;I&gt;&amp;, Us...&gt;</tt> is `true`,</p></li>
262+
<li><p>(20.4) &mdash; <tt>is_copy_constructible_v&lt;U&gt;</tt> is `true`, and</p></li>
263+
<li><p>(20.5) &mdash; <tt>is_default_constructible_v&lt;Allocator&gt;</tt> is `true`.</p></li>
264+
</ol>
265+
<p>
266+
<ins>-?- <i>Mandates:</i> <tt>derived_from&lt;U, T&gt;</tt> is `true`.</ins>
267+
<p/>
268+
-21- <i>Effects</i>: [&hellip;]
269+
</p>
270+
</blockquote>
271+
<pre>
272+
template&lt;class U, class I, class... Us&gt;
273+
constexpr explicit polymorphic(in_place_type_t&lt;U&gt;, initializer_list&lt;I&gt; ilist, Us&amp;&amp;... us);
274+
</pre>
275+
<blockquote>
276+
<p>
277+
-22- <i>Constraints</i>:
278+
</p>
279+
<ol style="list-style-type: none">
280+
<li><p>(22.1) &mdash; <tt>is_same_v&lt;remove_cvref_t&lt;U&gt;, U&gt;</tt> is `true`,</p></li>
281+
<li><p><del>(22.2) &mdash; <tt>derived_from&lt;U, T&gt;</tt> is `true`,</del></p></li>
282+
<li><p>(22.3) &mdash; <tt>is_constructible_v&lt;U, initializer_list&lt;I&gt;&amp;, Us...&gt;</tt> is `true`, and</p></li>
283+
<li><p>(22.4) &mdash; <tt>is_copy_constructible_v&lt;U&gt;</tt> is `true`.</p></li>
284+
</ol>
285+
<p>
286+
<ins>-?- <i>Mandates:</i> <tt>derived_from&lt;U, T&gt;</tt> is `true`.</ins>
287+
<p/>
288+
-23- <i>Effects</i>: [&hellip;]
289+
</p>
290+
</blockquote>
291+
</blockquote>
292+
293+
</li>
294+
295+
</ol>
296+
</resolution>
297+
298+
</issue>

0 commit comments

Comments
 (0)