<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 673: unique_ptr update</title>
<meta property="og:title" content="Issue 673: unique_ptr update">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue673.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#CD1">CD1</a> status.</em></p>
<h3 id="673"><a href="lwg-defects.html#673">673</a>. <code>unique_ptr</code> update</h3>
<p><b>Section:</b> 20.3.1 <a href="https://wg21.link/unique.ptr">[unique.ptr]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2007-05-04 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#unique.ptr">issues</a> in [unique.ptr].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Discussion:</b></p>
<p>
Since the publication of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html">N1856</a>
there have been a few small but significant advances which should be included into
<code>unique_ptr</code>.  There exists a
<a href="http://home.roadrunner.com/~hinnant/unique_ptr.hpp">example implementation</a>
for all of these changes.
</p>

<ul>

<li>
<p>
Even though <code>unique_ptr&lt;void&gt;</code> is not a valid use case (unlike for <code>shared_ptr&lt;void&gt;</code>),
unexpected cases to crop up which require the instantiation of the interface of <code>unique_ptr&lt;void&gt;</code>
even if it is never used.  For example see <a href="lwg-defects.html#541" title="shared_ptr template assignment and void (Status: CD1)">541</a><sup><a href="https://cplusplus.github.io/LWG/issue541" title="Latest snapshot">(i)</a></sup> for how this accidently happened to <code>auto_ptr</code>.  
I believe the most robust way to protect <code>unique_ptr</code> against this
type of failure is to augment the return type of <code>unique_ptr&lt;T&gt;:operator*()</code> with
<code>add_lvalue_reference&lt;T&gt;::type</code>.  This means that given an instantiated <code>unique_ptr&lt;void&gt;</code>
the act of dereferencing it will simply return <code>void</code> instead of causing a compile time failure.
This is simpler than creating a <code>unique_ptr&lt;void&gt;</code> specialization which isn't robust in the
face of <code><i>cv-</i></code>qualified <code>void</code> types.
</p>

<p>
This resolution also supports instantiations such as <code>unique_ptr&lt;void, free_deleter&gt;</code>
which could be very useful to the client.
</p>

</li>

<li>
<p>
Efforts have been made to better support containers and smart pointers in shared
memory contexts.  One of the key hurdles in such support is not assuming that a
pointer type is actually a <code>T*</code>.  This can easily be accomplished
for <code>unique_ptr</code> by having the deleter define the pointer type:
<code>D::pointer</code>.  Furthermore this type can easily be defaulted to
<code>T*</code> should the deleter <code>D</code> choose not to define a pointer
type (example implementation
<a href="http://home.roadrunner.com/~hinnant/unique_ptr.hpp">here</a>).
This change has no run time overhead.  It has no interface overhead on
authors of custom delter types.  It simply allows (but not requires)
authors of custom deleter types to define a smart pointer for the
storage type of <code>unique_ptr</code> if they find such functionality
useful.  <code>std::default_delete</code> is an example of a deleter which
defaults <code>pointer</code> to <code>T*</code> by simply ignoring this issue
and not including a <code>pointer typedef</code>.
</p>
</li>

<li>
<p>
When the deleter type is a function pointer then it is unsafe to construct
a <code>unique_ptr</code> without specifying the function pointer in the constructor.
This case is easy to check for with a <code>static_assert</code> assuring that the
deleter is not a pointer type in those constructors which do not accept deleters.
</p>

<blockquote><pre>
unique_ptr&lt;A, void(*)(void*)&gt; p(new A);  // error, no function given to delete the pointer!
</pre></blockquote>

</li>

</ul>

<p><i>[
Kona (2007): We don't like the solution given to the first bullet in
light of concepts. The second bullet solves the problem of supporting
fancy pointers for one library component only. The full LWG needs to
decide whether to solve the problem of supporting fancy pointers
piecemeal, or whether a paper addressing the whole library is needed. We
think that the third bullet is correct.
]</i></p>


<p><i>[
Post Kona: Howard adds example user code related to the first bullet:
]</i></p>


<blockquote>
<pre>
void legacy_code(void*, std::size_t);

void foo(std::size_t N)
{
    std::unique_ptr&lt;void, void(*)(void*)&gt; ptr(std::malloc(N), std::free);
    legacy_code(ptr.get(), N);
}   // unique_ptr used for exception safety purposes
</pre>
</blockquote>

<p>
I.e. <code>unique_ptr&lt;void&gt;</code> <i>is</i> a useful tool that we don't want
to disable with concepts.  The only part of <code>unique_ptr&lt;void&gt;</code> we
want to disable (with concepts or by other means) are the two member functions:
</p>

<blockquote><pre>
T&amp; operator*() const;
T* operator-&gt;() const;
</pre></blockquote>



<p id="res-673"><b>Proposed resolution:</b></p>

<p><i>[
I am grateful for the generous aid of Peter Dimov and Ion Gazta&ntilde;aga in helping formulate and review
the proposed resolutions below.
]</i></p>


<ul>
<li>

<p>
Change 20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a>:
</p>

<blockquote><pre>
template &lt;class T, class D = default_delete&lt;T&gt;&gt; class unique_ptr {
   ...
   <del>T&amp;</del> <ins>typename add_lvalue_reference&lt;T&gt;::type</ins> operator*() const;
   ...
};
</pre></blockquote>

<p>
Change 20.3.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a>:
</p>

<blockquote><pre>
<del>T&amp;</del> <ins>typename add_lvalue_reference&lt;T&gt;::type</ins> operator*() const;
</pre></blockquote>

</li>

<li>
<p>
Change 20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a>:
</p>

<blockquote><pre>
template &lt;class T, class D = default_delete&lt;T&gt;&gt; class unique_ptr {
public:
  <ins>typedef <i>implementation (see description below)</i> pointer;</ins>
   ...
   explicit unique_ptr(<del>T*</del> <ins>pointer</ins> p);
   ...
   unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined (see description below)</i> d);
   unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined (see description below)</i> d);
   ...
   <del>T*</del> <ins>pointer</ins> operator-&gt;() const;
   <del>T*</del> <ins>pointer</ins> get() const;
   ...
   <del>T*</del> <ins>pointer</ins> release();
   void reset(<del>T*</del> <ins>pointer</ins> p = <del>0</del> <ins>pointer()</ins>);
};
</pre></blockquote>

<p>
<ins>
-3- If the type <code>remove_reference&lt;D&gt;::type::pointer</code>
exists, then <code>unique_ptr&lt;T, D&gt;::pointer</code> is a typedef to
<code>remove_reference&lt;D&gt;::type::pointer</code>.  Otherwise
<code>unique_ptr&lt;T, D&gt;::pointer</code> is a typedef to <code>T*</code>.
The type <code>unique_ptr&lt;T, D&gt;::pointer</code> shall be <code>CopyConstructible</code>
and <code>CopyAssignable</code>.
</ins>
</p>

<p>
Change 20.3.1.3.2 <a href="https://wg21.link/unique.ptr.single.ctor">[unique.ptr.single.ctor]</a>:
</p>

<blockquote><pre>
unique_ptr(<del>T*</del> <ins>pointer</ins> p);
...
unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d); 
unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d); 
...
unique_ptr(<del>T*</del> <ins>pointer</ins> p, const A&amp; d);
unique_ptr(<del>T*</del> <ins>pointer</ins> p, A&amp;&amp; d);
...
unique_ptr(<del>T*</del> <ins>pointer</ins> p, A&amp; d); 
unique_ptr(<del>T*</del> <ins>pointer</ins> p, A&amp;&amp; d);
...
unique_ptr(<del>T*</del> <ins>pointer</ins> p, const A&amp; d); 
unique_ptr(<del>T*</del> <ins>pointer</ins> p, const A&amp;&amp; d);
...
</pre></blockquote>

<p>
-23- <i>Requires:</i> If <code>D</code> is not a reference type,
construction of the deleter <code>D</code> from an rvalue of type <code>E</code>
<del>must</del> <ins>shall</ins> be well formed and not throw an exception. If <code>D</code> is a
reference type, then <code>E</code> <del>must</del> <ins>shall</ins> be the same type as <code>D</code>
(diagnostic required). <del><code>U*</code></del> <ins><code>unique_ptr&lt;U,E&gt;::pointer</code></ins>
<del>must</del> <ins>shall</ins> be implicitly convertible to <del><code>T*</code></del>
<ins>pointer</ins>.
</p>

<p>
-25- <i>Postconditions:</i> <code>get() == value u.get()</code> had before
the construction, modulo any required offset adjustments resulting from
the cast from <del><code>U*</code></del>
<ins><code>unique_ptr&lt;U,E&gt;::pointer</code></ins> to <del><code>T*</code></del>
<ins>pointer</ins>. <code>get_deleter()</code> returns a reference to the
internally stored deleter which was constructed from
<code>u.get_deleter()</code>.
</p>

<p>
Change 20.3.1.3.4 <a href="https://wg21.link/unique.ptr.single.asgn">[unique.ptr.single.asgn]</a>:
</p>

<blockquote>
<p>
-8- <i>Requires:</i> Assignment of the deleter <code>D</code> from an rvalue
<code>D</code> <del>must</del> <ins>shall</ins> not throw an exception. <del><code>U*</code></del>
<ins><code>unique_ptr&lt;U,E&gt;::pointer</code></ins> <del>must</del> <ins>shall</ins> be implicitly
convertible to <del><code>T*</code></del> <ins>pointer</ins>.
</p>
</blockquote>

<p>
Change 20.3.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a>:
</p>

<blockquote>
<pre><del>T*</del> <ins>pointer</ins> operator->() const;</pre>
<p>...</p>
<pre><del>T*</del> <ins>pointer</ins> get() const;</pre>
</blockquote>

<p>
Change 20.3.1.3.6 <a href="https://wg21.link/unique.ptr.single.modifiers">[unique.ptr.single.modifiers]</a>:
</p>

<blockquote>
<pre><del>T*</del> <ins>pointer</ins> release();</pre>
<p>...</p>
<pre>void reset(<del>T*</del> <ins>pointer</ins> p = <del>0</del> <ins>pointer()</ins>);</pre>
</blockquote>

<p>
Change 20.3.1.4 <a href="https://wg21.link/unique.ptr.runtime">[unique.ptr.runtime]</a>:
</p>

<blockquote><pre>
template &lt;class T, class D&gt; class unique_ptr&lt;T[], D&gt; {
public:
  <ins>typedef <i>implementation</i> pointer;</ins>
   ...
   explicit unique_ptr(<del>T*</del> <ins>pointer</ins> p);
   ...
   unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d);
   unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d);
   ...
   <del>T*</del> <ins>pointer</ins> get() const;
   ...
   <del>T*</del> <ins>pointer</ins> release();
   void reset(<del>T*</del> <ins>pointer</ins> p = <del>0</del> <ins>pointer()</ins>);
};
</pre></blockquote>

<p>
Change 20.3.1.4.2 <a href="https://wg21.link/unique.ptr.runtime.ctor">[unique.ptr.runtime.ctor]</a>:
</p>

<blockquote>
<pre>
unique_ptr(<del>T*</del> <ins>pointer</ins> p);
unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d);
unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d);
</pre>

<p>
These constructors behave the same as in the primary template except
that they do not accept pointer types which are convertible to
<del><code>T*</code></del> <ins><code>pointer</code></ins>. [<i>Note:</i> One
implementation technique is to create private templated overloads of
these members. <i>-- end note</i>]
</p>
</blockquote>

<p>
Change 20.3.1.4.5 <a href="https://wg21.link/unique.ptr.runtime.modifiers">[unique.ptr.runtime.modifiers]</a>:
</p>

<blockquote>
<pre>
void reset(<del>T*</del> <ins>pointer</ins> p = <del>0</del> <ins>pointer()</ins>);
</pre>

<p>
-1- <i>Requires:</i> Does not accept pointer types which are convertible
to <del><code>T*</code></del> <ins><code>pointer</code></ins> (diagnostic
required). [<i>Note:</i> One implementation technique is to create a private
templated overload. <i>-- end note</i>]
</p>
</blockquote>

</li>

<li>

<p>
Change 20.3.1.3.2 <a href="https://wg21.link/unique.ptr.single.ctor">[unique.ptr.single.ctor]</a>:
</p>

<blockquote>
<pre>unique_ptr();</pre>
<blockquote>
<p>
<i>Requires:</i> <code>D</code> <del>must</del> <ins>shall</ins> be default constructible, and that
construction <del>must</del> <ins>shall</ins> not throw an exception. <code>D</code> <del>must</del> <ins>shall</ins> not be a
reference type <ins>or pointer type (diagnostic required)</ins>.
</p>
</blockquote>
<pre>unique_ptr(<del>T*</del> <ins>pointer</ins> p);</pre>
<blockquote>
<p>
<i>Requires:</i>  The expression <code>D()(p)</code> <del>must</del> <ins>shall</ins> be well formed.
The default constructor of <code>D</code> <del>must</del> <ins>shall</ins> not throw an exception.
<code>D</code> <del>must</del> <ins>shall</ins> not be a reference type <ins>or pointer type (diagnostic
required)</ins>.
</p>
</blockquote>
</blockquote>

</li>

</ul>






</body>
</html>
