Skip to content

Commit 94f7ab2

Browse files
committed
New issue from Jonathan: Disallow unique_ptr<T&, D>
1 parent 8415c19 commit 94f7ab2

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

xml/issue4144.xml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4144" status="New">
5+
<title>Disallow <code>unique_ptr&lt;T&amp;, D&gt;</code></title>
6+
<section><sref ref="[unique.ptr.single.general]"/></section>
7+
<submitter>Jonathan Wakely</submitter>
8+
<date>30 Aug 2024</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
It seems that we currently allow nonsensical specializations of `unique_ptr`
14+
such as <code>unique_ptr&lt;int&amp;, D&gt;</code>
15+
and <code>unique_ptr&lt;void()const, D&gt;</code>
16+
(a custom deleter that defines `D::pointer` is needed, because otherwise
17+
the `pointer` type would default to invalid types like
18+
<code>int&amp;*</code> or <code>void(*)()const</code>).
19+
There seems to be no reason to support these "unique pointer to reference"
20+
and "unique pointer to abominable function type" specializations,
21+
or any specialization for a type that you couldn't form a raw pointer to.
22+
</p>
23+
24+
<p>
25+
Prior to C++17, the major library implementations rejected such specializations
26+
as a side effect of the constraints for the
27+
<code>unique_ptr(auto_ptr&lt;U&gt;&amp;&amp;)</code> constructor
28+
being defined in terms of <code>is_convertible&lt;U*, T*&gt;</code>.
29+
This meant that overload resolution for any constructor of `unique_ptr`
30+
would attempt to form the type `T*` and fail if that was invalid.
31+
With the removal of `auto_ptr` in C++17, that constructor was removed
32+
and now <code>unique_ptr&lt;int&amp;, D&gt;</code> can be instantiated
33+
(assuming any zombie definition of `auto_ptr` is not enabled by the library).
34+
This wasn't intentional, but just an accident caused by not explicitly
35+
forbidding such types.
36+
</p>
37+
38+
<p>
39+
Discussion on the LWG reflector led to near-unanimous support for explicitly
40+
disallowing these specializations for non-pointable types.
41+
</p>
42+
</discussion>
43+
44+
<resolution>
45+
<p>
46+
This wording is relative to <paper num="N4988"/>.
47+
</p>
48+
49+
<ol>
50+
<li><p>Modify <sref ref="[unique.ptr.single.general]"/> as indicated:</p>
51+
<blockquote>
52+
<p><ins>-?-
53+
A program that instantiates the definition of
54+
<code>unique_ptr&lt;T, D&gt;</code>
55+
is ill-formed if `T*` is an invalid type.
56+
<br/>
57+
[<em>Note</em>:
58+
This prevents the intantiation of specializations such as
59+
<code>unique_ptr&lt;T&amp;, D&gt;</code>
60+
and <code>unique_ptr&lt;int() const, D&gt;</code>.
61+
&mdash; <em>end note</em>]
62+
</ins>
63+
</p>
64+
<p>-1-
65+
The default type for the template parameter `D` is `default_delete`.
66+
A client-supplied template argument `D` shall be a function object type
67+
(<sref ref="[function.objects]"/>), lvalue reference to function,
68+
or lvalue reference to function object type for which,
69+
given a value `d` of type `D` and a value `ptr` of type
70+
<code>unique_ptr&lt;T, D&gt;::pointer</code>,
71+
the expression `d(ptr)` is valid and has the effect of disposing of the pointer
72+
as appropriate for that deleter.
73+
</p>
74+
<p>-2-
75+
If the deleter’s type `D` is not a reference type,
76+
`D` shall meet the <em>Cpp17Destructible</em> requirements (Table 35).
77+
</p>
78+
<p>-3-
79+
If the <i>qualified-id</i> <code>remove_reference_t&lt;D&gt;::pointer</code>
80+
is valid and denotes a type (<sref ref="[temp.deduct]"/>),
81+
then <code>unique_ptr&lt;T, D&gt;::pointer</code>
82+
shall be a synonym for <code>remove_reference_t&lt;D&gt;::pointer</code>.
83+
Otherwise <code>unique_ptr&lt;T, D&gt;::pointer</code> shall be a synonym for
84+
<code>element_type*</code>.
85+
The type <code>unique_ptr&lt;T, D&gt;::pointer</code> shall meet the
86+
<em>Cpp17NullablePointer</em> requirements (Table 36).
87+
</p>
88+
<p>-4-
89+
[<em>Example 1</em>:
90+
 Given an allocator type `X` (<sref ref="[allocator.requirements.general]"/>)
91+
and letting `A` be a synonym for <code>allocator_traits&lt;X&gt;</code>,
92+
the types `A::pointer`, `A::const_pointer`, `A::void_pointer`,
93+
and `A::const_void_pointer` may be used as
94+
<code>unique_ptr&lt;T, D&gt;::pointer</code>.
95+
&mdash; <em>end example</em>]
96+
</p>
97+
</blockquote>
98+
</li>
99+
</ol>
100+
</resolution>
101+
102+
</issue>

0 commit comments

Comments
 (0)