<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2118: [CD] unique_ptr for array does not support cv qualification conversion of actual argument</title>
<meta property="og:title" content="Issue 2118: [CD] unique_ptr for array does not support cv qualification conversion of actual argument">
<meta property="og:description" content="C++ library issue. Status: Resolved">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2118.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#Resolved">Resolved</a> status.</em></p>
<h3 id="2118"><a href="lwg-defects.html#2118">2118</a>. [CD] <code>unique_ptr</code> for array does not support <i>cv</i> qualification conversion of actual argument</h3>
<p><b>Section:</b> 20.3.1.4 <a href="https://wg21.link/unique.ptr.runtime">[unique.ptr.runtime]</a> <b>Status:</b> <a href="lwg-active.html#Resolved">Resolved</a>
 <b>Submitter:</b> Alf P. Steinbach <b>Opened:</b> 2011-12-16 <b>Last modified:</b> 2017-09-07</p>
<p><b>Priority: </b>1
</p>
<p><b>View all other</b> <a href="lwg-index.html#unique.ptr.runtime">issues</a> in [unique.ptr.runtime].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Resolved">Resolved</a> status.</p>
<p><b>Discussion:</b></p>

<p><b>Addresses US 16</b></p>

<p>
N3290 20.3.1.4.2 <a href="https://wg21.link/unique.ptr.runtime.ctor">[unique.ptr.runtime.ctor]</a> "<code>unique_ptr</code> constructors":
</p>
<blockquote><p>
These constructors behave the same as in the primary template except that they do not accept pointer types 
which are convertible to <code>pointer</code>. [<i>Note:</i> One implementation technique is to create private 
templated overloads of these members. &mdash; <i>end note</i>]
</p></blockquote>
<p>
This language excludes even <code>pointer</code> itself as type for the actual argument.
<p/>
But of more practical concern is that both Visual C++ 10.0 and MinGW g++ 4.1.1 reject the code below, where 
only an implicit <i>cv</i> qualification is needed, which <i>cv</i> qualification is supported by the non-array 
version:
</p>
<blockquote><pre>
#include &lt;memory&gt;
using namespace std;

struct T {};

T* foo() { return new T; }
T const* bar() { return foo(); }

int main()
{
   unique_ptr&lt; T const &gt;       p1( bar() );        // OK
   unique_ptr&lt; T const [] &gt;    a1( bar() );        // OK

   unique_ptr&lt; T const &gt;       p2( foo() );        // OK
   unique_ptr&lt; T const [] &gt;    a2( foo() );        // <span style="color:#C80000;font-weight:bold">? this is line #15</span>
}
</pre></blockquote>
<p>
The <em>intent</em> seems to be clearly specified in 20.3.1.4 <a href="https://wg21.link/unique.ptr.runtime">[unique.ptr.runtime]</a>&#47;1 second bullet:
</p>
<blockquote><p>
&mdash; Pointers to types derived from <code>T</code> are rejected by the constructors, and by <code>reset</code>.
</p></blockquote>

<p>
But the following language in 20.3.1.4.2 <a href="https://wg21.link/unique.ptr.runtime.ctor">[unique.ptr.runtime.ctor]</a> then rejects far too much...
<p/>
Proposed new wording of N3290 20.3.1.4.2 <a href="https://wg21.link/unique.ptr.runtime.ctor">[unique.ptr.runtime.ctor]</a> "<code>unique_ptr</code> constructors":
</p>
<blockquote><p>
These constructors behave the same as in the primary template except that actual argument pointers <code>p</code> 
to types derived from <code>T</code> are rejected by the constructors. [<i>Note:</i> One implementation technique 
is to create private templated overloads of these members. &mdash; <i>end note</i>]
</p></blockquote>
<p>
This will possibly capture the intent better, and avoid the inconsistency between the non-array and array 
versions of <code>unique_ptr</code>, by using nearly the exact same phrasing as for the paragraph explaining 
the intent.
</p>

<p><i>[2012-08-25 Geoffrey Romer comments in <a href="http://listarchives.isocpp.org/cgi-bin/wg21/message?wg=lib&amp;msg=32978">c++std-lib-32978</a>]</i></p>


<ol>
<li><p>
The current P/R seems to intend to support at least two different implementation techniques &mdash; additional 
unusable templates that catch forbidden arguments or replacing existing constructors by templates that 
ensure ill-formed code inside the template body, when the requirements are not met. It seems unclear whether
the current wording allows the second approach, though. It should be considered to allow both strategies or
if that is not possible the note should be clearer.
</p></li>

<li><p>
The very same problem exists for the <code>reset</code> member function, but even worse, because the current
specification is more than clear that the deleted <code>reset</code> function will catch all cases not equal to 
<code>pointer</code>. It seems confusing at best to have different policies for the constructor and for the <code>reset</code> 
function. In this case, the question in regard to implementation freedom mentioned above is even more important.
</p></li>

<li><p>
It's awkward to refer to "the constructors" twice in the same sentence; I suggest revising the sentence as 
"...except that they do not accept argument pointers <code>p</code> to types derived from <code>T</code>"
</p></li>
</ol>

<p><i>[2012-12-20: Geoffrey Romer comments and provides a revised resolution]</i></p>


<p>
The array specialization of <code>unique_ptr</code> differs from the primary template in several ways,
including the following:
</p>
<ul>
<li><p>
<code>unique_ptr&lt;T[], D&gt;</code> cannot be constructed from a plain pointer whose type is not
exactly <code>unique_ptr&lt;T[], D&gt;::pointer</code> or <code>nullptr_t</code>.
</p></li>
<li><p>
<code>unique_ptr&lt;T[], D&gt;</code> cannot be constructed from a <code>unique_ptr&lt;U[], E&gt;&amp;&amp;</code> 
unless <code>U</code> is exactly <code>T</code> and <code>E</code> is exactly <code>D</code>.
</p></li>
<li><p>
<code>unique_ptr&lt;T[], D&gt;</code> cannot be moveassigned from a <code>unique_ptr&lt;U[], E&gt;&amp;&amp;</code> 
unless <code>U</code> is exactly <code>T</code> and <code>E</code> is exactly <code>D</code>.
</p></li>
<li><p>
<code>unique_ptr&lt;T[], D&gt;::reset</code> cannot take an argument whose type is not exactly
<code>unique_ptr&lt;T[], D&gt;::pointer</code> or <code>nullptr_t</code>.
</p></li>
<li><p>
<code>default_delete&lt;T[]&gt;</code> cannot be constructed from a <code>default_delete&lt;U[]&gt;</code> unless 
<code>U</code> is exactly <code>T</code>.
</p></li>
<li><p>
<code>default_delete&lt;T[]&gt;::operator()</code> cannot be called on a pointer whose type is not
exactly <code>T*</code>.
</p></li>
</ul>
<p>
The common intent of all these restrictions appears to be to disallow implicit conversions from
pointer-to-derived-class to pointer-to-base-class in contexts where the pointer is known to point
to an array, because such conversions are inherently unsafe; deleting or subscripting the result
of such a conversion leads to undefined behavior (see also CWG 1504). However, these restrictions 
have the effect of disallowing all implicit conversions in those contexts, including most notably 
cv-qualification, but also user-defined conversions, and possibly others. This PR narrows all those 
restrictions, to disallow only unsafe pointer-to-derived to pointer-to-base conversions, while 
allowing all others.
<p/>
I removed the nebulous language stating that certain functions "will not accept" certain arguments. 
Instead I use explicitly deleted template functions, which participate in overload resolution only 
for pointer-to-derived to pointer-to-base conversions. This is more consistent with the existing 
text and easier to express correctly than an approach based on declaring certain types of calls to 
be ill-formed, but may produce inferior compiler diagnostics.
<p/>
Wherever possible, this PR defines the semantics of template specializations in terms of their
differences from the primary template. This improves clarity and minimizes the risk of
unintended differences (e.g. LWG <a href="lwg-defects.html#2169" title="Missing reset() requirements in unique_ptr specialization (Status: C++14)">2169</a><sup><a href="https://cplusplus.github.io/LWG/issue2169" title="Latest snapshot">(i)</a></sup>, which this PR also fixes). This PR also makes it 
explicit that the specialization inherits the description of all members, not just member functions, 
from the primary template and, in passing, clarifies the default definition of pointer in the
specialization.
<p/>
This resolution only disallows pointer-to-derived to pointer-to-base conversions between
ordinary pointer types; if user-defined pointer types provide comparable conversions, it is their
responsibility to ensure they are safe. This is consistent with C++'s general preference for
expressive power over safety, and for assuming the user knows what they're doing;
furthermore, enforcing such a restriction on user-defined types appears to be impractical without
cooperation from the user.
<p/>
The "base class without regard to cv-qualifiers" language is intended to parallel the specification
of <code>std::is_base_of</code>.
<p/>
Jonathan Wakely has a working implementation of this PR patched into libstdc++.
</p>

<p>
Previous resolution:
</p>
<blockquote class="note">
<p>This wording is relative to the FDIS.</p>

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

<blockquote><pre>
explicit unique_ptr(pointer p) noexcept;
unique_ptr(pointer p, <i>see below</i> d) noexcept;
unique_ptr(pointer p, <i>see below</i> d) noexcept;
</pre>
<blockquote><p>
These constructors behave the same as in the primary template except that <del>they do not accept pointer
types which are convertible to <code>pointer</code></del><ins>argument pointers <code>p</code> to types derived 
from <code>T</code> are rejected by the constructors</ins>. [<i>Note:</i> One implementation technique is to 
create private templated overloads of these members. &mdash; <i>end note</i>]
</p></blockquote></blockquote>
</blockquote>

<p><i>[2014-02, Issaquah]</i></p>

<p>
GR: want to prevent unsafe conversions. Standard is inconsistent how it does this. for <code>reset()</code> has deleted function 
template capturing everything except the known-safe cases. Other functions use SFINAE. Main reason this is hard is that 
<code>unique_ptr</code> supports fancy pointers. Have to figure out how to handle them and what requirements to put on them. 
Requirements are minimal, not even required to work with <code>pointer_traits</code>.
<p/>
STL surprised <code>pointer_traits</code> doesn't work
<p/>
GR: ways to get fancy pointers to work is to delegate responsibility for preventing unsafe conversions to the fancy pointers themselves. 
Howard doesn't like that, he wants even fancy pointers to be prevented from doing unsafe conversions in <code>unique_ptr</code> contexts.
<p/>
AM: Howard says <code>unique_ptr</code> was meant to be very very safe under all conditions, this open a hole in that. Howard wants to 
eke forward and support more, but not if we open any holes in type safety. 
<p/>
GR: do we need to be typesafe even for fancy types with incorrect <code>pointer_traits</code>?
<p/>
AM: that would mean it's only unsafe for people who lie by providing a broken specialization of <code>pointer_traits</code>
<p/>
GR: probably can't continue with ambiguity between using SFINAE and ill-formedness. Would appreciate guidance on direction used for that.
<p/>
STL: difference is observable in convertibility using type traits. 
<p/>
STL: for <code>reset()</code> which doesn't affect convertibility ill-formed allows <code>static_assert</code>, better diagnostic. 
For assignment it's detectable and has traits, constraining them is better.
<p/>
EN: I strongly prefer constraints than <code>static_asserts</code> 
<p/>
STL: if we could rely on <code>pointer_traits</code> that might be good. Alternatively could we add more machinery to deleter? 
make deleter say conversions are allowed, otherwise we lock down all conversions. basically want to know if converting <code>U</code> to 
<code>T</code> is safe.
</p>

<p>
<strong>Previous resolution [SUPERSEDED]:</strong>
</p>
<blockquote class="note">
<p>This wording is relative to N3485.</p>
<ol>
<li><p>Revise 20.3.1.2.3 <a href="https://wg21.link/unique.ptr.dltr.dflt1">[unique.ptr.dltr.dflt1]</a> as follows</p>
<blockquote><pre>
namespace std {
  template &lt;class T&gt; struct default_delete&lt;T[]&gt; {
    constexpr default_delete() noexcept = default;
    <ins>template &lt;class U&gt; default_delete(const default_delete&lt;U&gt;&amp;) noexcept;</ins>
    void operator()(T*) const;
    template &lt;class U&gt; void operator()(U*) const = delete;
  };
}
</pre></blockquote>
<p>
<ins>-?- Descriptions are provided below only for member functions that have behavior different from the
primary template.</ins>
</p>
<blockquote>
<pre>
<ins>template &lt;class U&gt; default_delete(const default_delete&lt;U&gt;&amp;) noexcept;</ins>
</pre>
<blockquote><p>
<ins>-?- This constructor behaves the same as in the primary template except that it shall not participate
in overload resolution unless:</ins>
</p>
<ul>
<li><p>
<ins><code>U</code> is an array type, and</ins>
</p></li>
<li><p>
<ins><code>V*</code> is implicitly convertible to <code>T*</code>, and</ins>
</p></li>
<li><p>
<ins><code>T</code> is not a base class of <code>V</code> (without regard to <i>cv</i>-qualifiers),</ins>
</p></li>
</ul>
<p>
<ins>where <code>V</code> is the array element type of <code>U</code>.</ins>
</p>
</blockquote>

<blockquote><pre>
void operator()(T* ptr) const;
</pre><blockquote>
<p>
-1- <i>Effects</i>: calls <code>delete[]</code> on <code>ptr</code>.
<p/>
-2- <i>Remarks</i>: If <code>T</code> is an incomplete type, the program is ill-formed.
</p>
</blockquote></blockquote>

<blockquote><pre>
<ins>template &lt;class U&gt; void operator()(U*) const = delete;</ins>
</pre><blockquote>
<p>
<ins>-?- <i>Remarks</i>: This function shall not participate in overload resolution unless <code>T</code> is a base 
class of <code>U</code> (without regard to <i>cv</i>-qualifiers).</ins>
</p>
</blockquote></blockquote>

</blockquote>
</li>

<li><p>Revise 20.3.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a>/3 as follows:</p>
<blockquote><p>
If the type <code>remove_reference&lt;D&gt;::type::pointer</code> exists, then <code>unique_ptr&lt;T, D&gt;::pointer</code> 
shall be a synonym for <code>remove_reference&lt;D&gt;::type::pointer</code>. Otherwise <code>unique_ptr&lt;T, D&gt;::pointer</code> 
shall be a synonym for <code><del>T</del><ins>element_type</ins>*</code>. The type <code>unique_ptr&lt;T, D&gt;::pointer</code> 
shall satisfy the requirements of <code>NullablePointer</code> (16.4.4.4 <a href="https://wg21.link/nullablepointer.requirements">[nullablepointer.requirements]</a>).
</p></blockquote>
</li>

<li><p>Revise 20.3.1.4 <a href="https://wg21.link/unique.ptr.runtime">[unique.ptr.runtime]</a> as follows:</p>
<blockquote><pre>
namespace std {
  template &lt;class T, class D&gt; class unique_ptr&lt;T[], D&gt; {
  public:
    typedef <i>see below</i> pointer;
    typedef T element_type;
    typedef D deleter_type;

    <i>// 20.7.1.3.1, constructors</i>
    constexpr unique_ptr() noexcept;
    explicit unique_ptr(pointer p) noexcept;
    <ins>template &lt;class U&gt; explicit unique_ptr(U* p) = delete;</ins>
    unique_ptr(pointer p, <i>see below</i> d) noexcept;
    <ins>template &lt;class U&gt; unique_ptr(U* p, <i>see below</i> d) = delete;</ins>
    unique_ptr(pointer p, <i>see below</i> d) noexcept;
    <ins>template &lt;class U&gt; unique_ptr(U* p, <i>see below</i> d) = delete;</ins>
    unique_ptr(unique_ptr&amp;&amp; u) noexcept;
    constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
    <ins>template &lt;class U, class E&gt; unique_ptr(unique_ptr&lt;U, E&gt;&amp;&amp; u) noexcept;</ins>

    <i>// destructor</i>
    ~unique_ptr();

    <i>// assignment</i>
    unique_ptr&amp; operator=(unique_ptr&amp;&amp; u) noexcept;
    <ins>template &lt;class U, class E&gt; unique_ptr&amp; operator=(unique_ptr&lt;U, E&gt;&amp;&amp; u) noexcept;</ins>
    unique_ptr&amp; operator=(nullptr_t) noexcept;

    <i>// 20.7.1.3.2, observers</i>
    T&amp; operator[](size_t i) const;
    pointer get() const noexcept;
    deleter_type&amp; get_deleter() noexcept;
    const deleter_type&amp; get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    <i>// 20.7.1.3.3 modifiers</i>
    pointer release() noexcept;
    void reset(pointer p = pointer()) noexcept;
    <del>void reset(nullptr_t) noexcept;</del>
    template &lt;class U&gt; void reset(U<ins>*</ins>) = delete;
    void swap(unique_ptr&amp; u) noexcept;

    <i>// disable copy from lvalue</i>
    unique_ptr(const unique_ptr&amp;) = delete;
    unique_ptr&amp; operator=(const unique_ptr&amp;) = delete;
  };
}
</pre></blockquote>
<blockquote><p>
-1- A specialization for array types is provided with a slightly altered interface.
</p>
<ul>
<li><p>
Conversions <del>between different types of <code>unique_ptr&lt;T[], D&gt;</code></del><ins>from
<code>unique_ptr&lt;Derived[]&gt;</code> to <code>unique_ptr&lt;Base[]&gt;</code>, where <code>Base</code> is a 
base class of <code>Derived</code>, from <code>auto_ptr</code>,</ins> or to or from the non-array forms of
<code>unique_ptr</code> produce an ill-formed program.
</p></li>
<li><p>
Pointers to types derived from <code>T</code> are rejected by the constructors, and by <code>reset</code>.
</p></li>
<li><p>
The observers <code>operator*</code> and <code>operator-&gt;</code> are not provided.
</p></li>
<li><p>
The indexing observer <code>operator[]</code> is provided.
</p></li>
<li><p>
The default deleter will call <code>delete[]</code>.
</p></li>
</ul>
<p>
-2- Descriptions are provided below only for <del>member functions that have behavior 
different</del><ins>members that differ</ins> from the primary template.
<p/>
-3- The template argument <code>T</code> shall be a complete type.
</p>
</blockquote>
</li>

<li><p>Revise 20.3.1.4.2 <a href="https://wg21.link/unique.ptr.runtime.ctor">[unique.ptr.runtime.ctor]</a> as follows:</p>
<blockquote>
<pre>
<del>explicit unique_ptr(pointer p) noexcept;
unique_ptr(pointer p, <i>see below</i> d) noexcept;
unique_ptr(pointer p, <i>see below</i> d) noexcept;</del>
<ins>template &lt;class U&gt; explicit unique_ptr(U* p) = delete;</ins>
<ins>template &lt;class U&gt; unique_ptr(U* p, <i>see below</i> d) = delete;</ins>
<ins>template &lt;class U&gt; unique_ptr(U* p, <i>see below</i> d) = delete;</ins>
</pre><blockquote><p>
<del>These constructors behave the same as in the primary template except that they do not accept pointer
types which are convertible to pointer. [<i>Note</i>: One implementation technique is to create private
templated overloads of these members. &mdash; <i>end note</i>]</del><ins>These constructors shall not 
participate in overload resolution unless:</ins></p>
<ul>
<li><p><ins><code>pointer</code> is a pointer type, and</ins></p></li>
<li><p><ins><code>U*</code> is implicitly convertible to <code>pointer</code>, and</ins></p></li>
<li><p><ins><code>T</code> is a base class of <code>U</code> (without regard to <i>cv</i>-qualifiers).</ins></p></li>
</ul>
<p><ins>The type of <code>d</code> is determined as in the corresponding non-deleted constructors.</ins></p>
</blockquote>
<pre>
<ins>template &lt;class U, class E&gt; unique_ptr(unique_ptr&lt;U, E&gt;&amp;&amp; u) noexcept;</ins>
</pre><blockquote><p>
<ins>-?- This constructor behaves the same as in the primary template, except that it shall not participate
in overload resolution unless:</ins>
</p>
<ul>
<li><p><ins><code>unique_ptr&lt;U, E&gt;::pointer</code> is implicitly convertible to <code>pointer</code>, and</ins></p></li>
<li><p><ins><code>U</code> is an array type, and</ins></p></li>
<li><p><ins>either <code>D</code> is a reference type and <code>E</code> is the same type as <code>D</code>, or <code>D</code> 
is not a reference type and <code>E</code> is implicitly convertible to <code>D</code>, and</ins></p></li>
<li><p><ins>either at least one of <code>pointer</code> and <code>unique_ptr&lt;U, E&gt;::pointer</code> is not a 
pointer type, or <code>T</code> is not a base class of the array element type of <code>U</code> (without regard to 
<i>cv</i>-qualifiers).</ins></p></li>
</ul>
</blockquote></blockquote>
</li>

<li><p>Insert a new sub-clause following 20.3.1.4.2 <a href="https://wg21.link/unique.ptr.runtime.ctor">[unique.ptr.runtime.ctor]</a> as follows:</p>

<p><ins>?? <code>unique_ptr</code> assignment [unique.ptr.runtime.asgn]</ins></p>

<blockquote>
<pre>
<ins>template &lt;class U, class E&gt; unique_ptr&amp; operator=(unique_ptr&lt;U, E&gt;&amp;&amp; u) noexcept;</ins>
</pre><blockquote><p>
<ins>-?- This operator behaves the same as in the primary template, except that it shall not participate in
overload resolution unless:</ins></p>
<ul>
<li><p><ins><code>unique_ptr&lt;U, E&gt;::pointer</code> is implicitly convertible to <code>pointer</code>, and</ins></p></li>
<li><p><ins><code>U</code> is an array type, and</ins></p></li>
<li><p><ins>either <code>D</code> is a reference type and <code>E</code> is the same type as <code>D</code>, or <code>D</code> 
is not a reference type and <code>E</code> is implicitly convertible to <code>D</code>, and</ins></p></li>
<li><p><ins>either at least one of <code>pointer</code> and <code>unique_ptr&lt;U, E&gt;::pointer</code> is not a 
pointer type, or <code>T</code> is not a base class of the array element type of <code>U</code> (without regard to 
<i>cv</i>-qualifiers).</ins></p></li>
</ul>
</blockquote></blockquote>
</li>

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

<blockquote>
<pre>
<del>void reset(pointer p = pointer()) noexcept;
void reset(nullptr_t p) noexcept;</del>
<ins>template &lt;class U&gt; void reset(U*) = delete;</ins>
</pre><blockquote><p>
<del>-1- <i>Effects</i>: If <code>get() == nullptr</code> there are no effects. Otherwise <code>get_deleter()(get())</code>.</del>
<p/>
<del>-2- <i>Postcondition</i>: <code>get() == p</code>.</del>
<p/>
<ins>-?- This function shall not participate in overload resolution unless:</ins>
</p>
<ul>
<li><p><ins><code>pointer</code> is a pointer type, and</ins></p></li>
<li><p><ins><code>U*</code> is implicitly convertible to <code>pointer</code>, and</ins></p></li>
<li><p><ins><code>T</code> is a base class of <code>U</code> (without regard to <i>cv</i>-qualifiers).</ins></p></li>
</ul>

</blockquote></blockquote>
</li>
</ol>
</blockquote>

<p><i>[2014-06 Rapperswil]</i></p>

<p>
Discussion of N4042 and general agreement that this paper resolves the substance of this issue and should be adopted with 
minor edits. Geoffrey Romer will provide an updated paper. 
</p>

<p><i>[2014-06 post-Rapperswil]</i></p>

<p>
As described in N4089.
</p>

<p><i>[2014-11-07 Urbana]</i></p>

<p>
Resolved by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4089.pdf">N4089</a>
</p>



<p id="res-2118"><b>Proposed resolution:</b></p>
<p>
See proposed wording in N4089.
</p>





</body>
</html>
