<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2756: C++ WP optional&lt;T&gt; should 'forward' T's implicit conversions</title>
<meta property="og:title" content="Issue 2756: C++ WP optional&lt;T&gt; should 'forward' T's implicit conversions">
<meta property="og:description" content="C++ library issue. Status: C++17">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2756.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#C++17">C++17</a> status.</em></p>
<h3 id="2756"><a href="lwg-defects.html#2756">2756</a>. C++ WP <code>optional&lt;T&gt;</code> should 'forward' <code>T</code>'s implicit conversions</h3>
<p><b>Section:</b> 22.5.3 <a href="https://wg21.link/optional.optional">[optional.optional]</a> <b>Status:</b> <a href="lwg-active.html#C++17">C++17</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2016-07-26 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>1
</p>
<p><b>View all other</b> <a href="lwg-index.html#optional.optional">issues</a> in [optional.optional].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++17">C++17</a> status.</p>
<p><b>Discussion:</b></p>
<p>
LWG <a href="lwg-defects.html#2451" title="[fund.ts.v2] optional&lt;T&gt; should 'forward' T's implicit conversions (Status: TS)">2451</a><sup><a href="https://cplusplus.github.io/LWG/issue2451" title="Latest snapshot">(i)</a></sup> adds converting constructors and assignment operators to <code>optional</code>. The committee 
voted to apply it to the Library Fundamentals 2 TS WP in Oulu as part of LWG Motion 3. In both LWG and LEWG 
discussion of this issue, it was considered to be critical to apply to the specification of <code>optional</code> 
before shipping C++17 &mdash; it was an oversight on the part of LWG that there was no motion brought to apply 
this resolution to the C++ WP.
<p/>
LWG <a href="lwg-defects.html#2745" title="[fund.ts.v2] Implementability of LWG 2451 (Status: TS)">2745</a><sup><a href="https://cplusplus.github.io/LWG/issue2745" title="Latest snapshot">(i)</a></sup> proposes removal of the <code>constexpr</code> specifier from the declarations of the 
converting constructors from <code>const optional&lt;U&gt;&amp;</code> and <code>optional&lt;U&gt;&amp;&amp;</code> 
since they are not implementable as <code>constexpr</code> constructors in C++17.
<p/>
This issue proposes application of the resolution of LWG <a href="lwg-defects.html#2451" title="[fund.ts.v2] optional&lt;T&gt; should 'forward' T's implicit conversions (Status: TS)">2451</a><sup><a href="https://cplusplus.github.io/LWG/issue2451" title="Latest snapshot">(i)</a></sup> as amended by LWG <a href="lwg-defects.html#2745" title="[fund.ts.v2] Implementability of LWG 2451 (Status: TS)">2745</a><sup><a href="https://cplusplus.github.io/LWG/issue2745" title="Latest snapshot">(i)</a></sup> 
to the specification of <code>optional</code> in the C++ WP.
</p>

<p><i>[2016-07 &mdash; Chicago]</i></p>

<p>Monday: Priority set to 1; will re-review later in the week</p>

<p><i>[2016-08-03, Tomasz comments]</i></p>

<ol>
<li><p>Value forwarding constructor (<code>template&lt;typename U&gt; optional(U&amp;&amp;)</code>) is underspecified.</p>
<p>For the following use code:</p>

<blockquote><pre>
optional&lt;T&gt; o1;
optional&lt;T&gt; o2(o1);
</pre></blockquote>

<p>
The second constructor will invoke value forwarding <code>(U = optional&lt;T&gt;&amp;)</code> constructor (better match) 
instead of the <code>optional&lt;T&gt;</code> copy constructor, in case if <code>T</code> can be constructed from 
<code>optional&lt;T&gt;</code>. This happens for any type <code>T</code> that has unconstrained perfect forwarding constructor, 
especially <code>optional&lt;any&gt;</code>.
</p>
</li>
<li>
<p>The behavior of the construction of the <code>optional&lt;T&gt; ot</code> from <code>optional&lt;U&gt; ou</code> is 
inconsistent for classes <code>T</code> than can be constructed both from <code>optional&lt;U&gt;</code> and <code>U</code>. 
There are two possible semantics for such operation:
</p>
<ul>
<li><p><em>unwrapping:</em> if <code>ou</code> is initialized (<code>bool(ou)</code>), initialize contained value of <code>ot</code> 
from <code>*ou</code>, otherwise make <code>ot</code> uninitialized (<code>!bool(ot)</code>)</p></li>
<li><p><em>value forwarding:</em> initialize contained value of <code>ot</code> from <code>ou</code>, <code>ot</code> is always 
initialized (<code>bool(ot)</code>). 
<p/>
With the proposed resolution, construction is preferring <em>value forwarding</em>, 
while assignment is always using <em>unwrapping</em>.</p></li>
</ul>
<p>
For example, if we consider following class:
</p>
<blockquote>
<pre>
struct Widget
{
  Widget(int);
  Widget(optional&lt;int&gt;);
};
</pre>
</blockquote>
<p>
Notice, that such set of constructor is pretty common in situation when the construction of the 
<code>Widget</code> from known value is common and usage of <code>optional</code> version is rare. In such situation, 
presence of <code>Widget(int)</code> construction is an optimization used to avoid unnecessary empty checks and 
construction <code>optional&lt;int&gt;</code>.
<p/>
For the following declarations:
</p>
<blockquote>
<pre>
optional&lt;Widget&gt; w1(make_optional(10));
optional&lt;Widget&gt; w2;
w2 = make_optional(10);
</pre>
</blockquote>
<p>
The <code>w1</code> will contain a value created using <code>Widget(optional&lt;int&gt;)</code> constructor, 
as corresponding <em>unwrapping</em> constructor (<code>optional&lt;U&gt; const&amp;</code>) is eliminated by 
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> 
(<code>is_constructible_v&lt;Widget, const optional&lt;int&gt;&amp;&gt;</code>) having a <code>true</code> value.
In contrast <code>w2</code> will contain a value created using <code>Widget(int)</code> constructor, as corresponding 
value forwarding assignment (<code>U&amp;&amp;</code>) is eliminated by the fact that 
<code>std::decay_t&lt;U&gt;</code> (<code>optional&lt;int&gt;</code>) is specialization of <code>optional</code>.
<p/>
In addition, the construction is having a preference for <em>value forwarding</em> and assignment is always using 
<em>unwrapping</em>. That means that for the following class:
</p>
<blockquote><pre>
struct Thingy
{
   Thingy(optional&lt;string&gt;);
};

optional&lt;Thingy&gt; t1(optional&lt;string&gt;("test"));
</pre></blockquote>
<p>
The <code>t1</code> has a contained value constructed from using <code>Thingy(optional&lt;std::string&gt;)</code>, 
as unwrapping constructor (<code>optional&lt;U&gt; const&amp;</code>) are eliminated by the 
<code>is_constructible&lt;T, U const&amp;&gt;</code> (<code>is_constructible&lt;Thingy, std::string const&amp;&gt;</code>) 
being <code>false</code>. However the following:
</p>
<blockquote><pre>
t1 = optional&lt;std::string&gt;("test2");
</pre></blockquote>
<p>
will not compile, because, the <em>value forwarding</em> assignment (<code>U&amp;&amp;</code>) is eliminated by 
<code>std::decay_t&lt;U&gt;</code> (<code>optional&lt;std::string&gt;</code>) being optional specialization and the 
<em>unwrapping</em> assignment (<code>optional&lt;U&gt; const&amp;</code>) is ill-formed because 
<code>is_constructible&lt;T, U const&amp;&gt;</code> (<code>is_constructible&lt;Thingy, std::string const&amp;&gt;</code>) 
is <code>false</code>.
</p>
</li>
<li>
<p>
The semantics of construction and assignment, of <code>optional&lt;optional&lt;V&gt;&gt;</code> from 
<code>optional&lt;U&gt;</code> where <code>U</code> is convertible to/ same as <code>T</code> is also inconsistent. Firstly, 
in this situation the <code>optional&lt;V&gt;</code> is a type that can be constructed both from 
<code>optional&lt;U&gt;</code> and <code>U</code> so it fails into set of problem described above. However in 
addition we have following non-template constructor in <code>optional&lt;T&gt;</code>:
</p>
<blockquote><pre>
optional(T const&amp;);
</pre></blockquote>
<p>
Which for <code>optional&lt;optional&lt;V&gt;&gt;</code> is equivalent to:
</p>
<blockquote><pre>
optional(optional&lt;V&gt; const&amp;);
</pre></blockquote>
<p>
While there is no corresponding non-template assignment from <code>T const&amp;</code>, to make sure that 
<code>o = {};</code> always clear an <code>optional o</code>.
<p/>
So for the following declarations:
</p>
<blockquote><pre>
optional&lt;int&gt; oi;
optional&lt;short&gt; os;

optional&lt;optional&lt;int&gt;&gt; ooi1(oi);
optional&lt;optional&lt;int&gt;&gt; ooi2(os);
</pre></blockquote>
<p>
The <code>ooi1</code> uses <em>from-<code>T</code></em> constructor, while <code>ooi2</code> uses <em>value forwarding</em> constructor. 
In this case both <code>ooi1</code> and <code>ooi2</code> are initialized and their contained values <code>*ooi1</code>, 
<code>*ooi2</code> are uninitialized <code>optional</code>s. However, if we will attempt to make construction consistent 
with assignment, by preferring <em>unwrapping</em> (<code>optional&lt;U&gt; const&amp;</code>), then <code>ooi2</code> 
will end up being uninitialized.
<p/>
In summary, I believe that relation between <em>unwrapping</em>, <em>value forwarding</em> and 
<em>from-<code>T</code></em> construction/assignment is to subtle to being handled as defect report and requires 
a full paper analyzing possible design and their pros/cons.
</p>
</li>
</ol>

<p>Tuesday PM: Ville and Eric to implement and report back in Issaquah. Moved to Open</p>
<p>Ville notes that <a href="lwg-active.html#2746" title="Inconsistency between requirements for emplace between optional and variant (Status: New)">2746</a><sup><a href="https://cplusplus.github.io/LWG/issue2746" title="Latest snapshot">(i)</a></sup>, <a href="lwg-defects.html#2754" title="The in_place constructors and emplace functions added by P0032R3 don't require CopyConstructible (Status: Resolved)">2754</a><sup><a href="https://cplusplus.github.io/LWG/issue2754" title="Latest snapshot">(i)</a></sup> and <a href="lwg-defects.html#2756" title="C++ WP optional&lt;T&gt; should 'forward' T's implicit conversions (Status: C++17)">2756</a><sup><a href="https://cplusplus.github.io/LWG/issue2756" title="Latest snapshot">(i)</a></sup> all go together.</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to N4606.</p>

<ol>
<li><p>Modify 22.5.3 <a href="https://wg21.link/optional.optional">[optional.optional]</a> as indicated:</p>

<blockquote>
<pre>
template &lt;class T&gt; class optional
{
public:
  using value_type = T;
  
  <i>// 20.6.3.1, Constructors</i>
  constexpr optional() noexcept;
  constexpr optional(nullopt_t) noexcept;
  optional(const optional &amp;);
  optional(optional &amp;&amp;) noexcept(<i>see below</i>);
  constexpr optional(const T &amp;);
  constexpr optional(T &amp;&amp;);
  template &lt;class... Args&gt; constexpr explicit optional(in_place_t, Args &amp;&amp;...);
  template &lt;class U, class... Args&gt;
    constexpr explicit optional(in_place_t, initializer_list&lt;U&gt;, Args &amp;&amp;...);
  <ins>template &lt;class U&gt; constexpr optional(U &amp;&amp;);
  template &lt;class U&gt; optional(const optional&lt;U&gt; &amp;);
  template &lt;class U&gt; optional(optional&lt;U&gt; &amp;&amp;);</ins>
  
  [&hellip;]
  
  <i>// 20.6.3.3, Assignment</i>
  optional &amp;operator=(nullopt_t) noexcept;
  optional &amp;operator=(const optional &amp;);
  optional &amp;operator=(optional &amp;&amp;) noexcept(<i>see below</i>);
  template &lt;class U&gt; optional &amp;operator=(U &amp;&amp;);
  <ins>template &lt;class U&gt; optional&amp; operator=(const optional&lt;U&gt; &amp;);
  template &lt;class U&gt; optional&amp; operator=(optional&lt;U&gt; &amp;&amp;);</ins>
  template &lt;class... Args&gt; void emplace(Args &amp;&amp;...);
  template &lt;class U, class... Args&gt;
    void emplace(initializer_list&lt;U&gt;, Args &amp;&amp;...);

  [&hellip;]
  
};
</pre>
</blockquote>
</li>

<li><p>In  [optional.object.ctor], insert new signature specifications after p31:</p>

<blockquote>
<p>
<ins>[<i>Note</i>: The following constructors are conditionally specified as <code>explicit</code>. This is typically 
implemented by declaring two such constructors, of which at most one participates in overload resolution. &mdash; 
<i>end note</i>]</ins>
</p>
<pre>
<ins>template &lt;class U&gt;
constexpr optional(U&amp;&amp; v);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: Initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> 
with the expression <code>std::forward&lt;U&gt;(v)</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>*this</code> contains a value.</ins>
<p/>
<ins>-?- <i>Throws</i>: Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor 
    shall be a <code>constexpr</code> constructor. This constructor shall not participate in overload resolution unless 
    <code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is <code>true</code> and <code>U</code> is not the same type as <code>T</code>.
    The constructor is <code>explicit</code> if and only if <code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt;
optional(const optional&lt;U&gt;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: If <code>rhs</code> contains a value, initializes the contained value as if direct-non-list-initializing 
an object of type <code>T</code> with the expression <code>*rhs</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Throws</i>: Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: This constructor shall not participate in overload resolution unless 
<code>is_constructible_v&lt;T, const U&amp;&gt;</code> is <code>true</code>, <code>is_same&lt;decay_t&lt;U&gt;, T&gt;</code> is 
<code>false</code>, <code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code> and 
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>. The constructor is <code>explicit</code> 
if and only if <code>is_convertible_v&lt;const U&amp;, T&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt;
optional(optional&lt;U&gt;&amp;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: If <code>rhs</code> contains a value, initializes the contained value as if 
direct-non-list-initializing an object of type <code>T</code> with the expression <code>std::move(*rhs)</code>. 
<code>bool(rhs)</code> is unchanged.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Throws</i>: Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: This constructor shall not participate in overload resolution unless 
<code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is <code>true</code>, <code>is_same&lt;decay_t&lt;U&gt;, T&gt;</code> is 
<code>false</code>, <code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code> and 
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code> and <code>U</code> is not the same type 
as <code>T</code>. The constructor is <code>explicit</code> if and only if <code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code>
is <code>false</code>.</ins>
</p>
</blockquote>
</blockquote>
</li>

<li><p>In  [optional.object.assign], change as indicated:</p>

<blockquote>
<pre>
template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(U&amp;&amp; v);
</pre>
<blockquote>
<p>
-22- <i>Remarks:</i> If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>v</code> is determined by the 
exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s 
assignment, the state of <code>*val</code> and <code>v</code> is determined by the exception safety guarantee of <code>T</code>'s 
assignment. The function shall not participate in overload resolution unless 
<ins><ins><code>decay_t&lt;U&gt;</code> is not <code>nullopt_t</code> and <code>decay_t&lt;U&gt;</code> is not a specialization of 
<code>optional</code></ins></ins><del><code>is_same_v&lt;decay_t&lt;U&gt;, T&gt;</code> is <code>true</code></del>.
<p/>
<del>-23- <i>Notes</i>: The reason for providing such generic assignment and then constraining it so that effectively 
<code>T == U</code> is to guarantee that assignment of the form <code>o = {}</code> is unambiguous.</del>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(const optional&lt;U&gt;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Requires</i>: <code>is_constructible_v&lt;T, const U&amp;&gt;</code> is <code>true</code> and 
<code>is_assignable_v&lt;T&amp;, const U&amp;&gt;</code> is <code>true</code>.</ins>
<p/>
<ins>-?- <i>Effects</i>:</ins>
</p>
<table border="1">
<caption><ins>Table ? &mdash; <code>optional::operator=(const optional&lt;U&gt;&amp;)</code> effects</ins></caption>

<tr>
<th></th>
<th><ins><b><code>*this</code> contains a value</b></ins></th>
<th><ins><b><code>*this</code> does not contain a value</b></ins></th>
</tr>

<tr>
<td><ins><b><code>rhs</code> contains a value</b></ins></td>
<td><ins>assigns <code>*rhs</code> to the contained value</ins></td>
<td><ins>initializes the contained value as if direct-non-list-initializing an object of type 
<code>T</code> with <code>*rhs</code></ins></td>
</tr>

<tr>
<td><ins><b><code>rhs</code> does not contain a value</b></ins></td>
<td><ins>destroys the contained value by calling <code>val-&gt;T::~T()</code></ins></td>
<td><ins>no effect</ins></td>
</tr>

</table> 
<p>
<ins>-?- <i>Returns</i>: <code>*this</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the 
exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s assignment, 
the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s assignment. 
The function shall not participate in overload resolution unless <code>is_same_v&lt;decay_t&lt;U&gt;, T&gt;</code> is 
<code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(optional&lt;U&gt;&amp;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Requires</i>: <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code> and 
<code>is_assignable_v&lt;T&amp;, U&gt;</code> is <code>true</code>.</ins>
<p/>
<ins>-?- <i>Effects</i>: The result of the expression <code>bool(rhs)</code> remains unchanged. </ins>
</p>
<table border="1">
<caption><ins>Table ? &mdash; <code>optional::operator=(optional&lt;U&gt;&amp;&amp;)</code> effects</ins></caption>

<tr>
<th></th>
<th><ins><b><code>*this</code> contains a value</b></ins></th>
<th><ins><b><code>*this</code> does not contain a value</b></ins></th>
</tr>

<tr>
<td><ins><b><code>rhs</code> contains a value</b></ins></td>
<td><ins>assigns <code>std::move(*rhs)</code> to the contained value</ins></td>
<td><ins>initializes the contained value as if direct-non-list-initializing an object of type 
<code>T</code> with <code>std::move(*rhs)</code></ins></td>
</tr>

<tr>
<td><ins><b><code>rhs</code> does not contain a value</b></ins></td>
<td><ins>destroys the contained value by calling <code>val-&gt;T::~T()</code></ins></td>
<td><ins>no effect</ins></td>
</tr>

</table> 
<p>
<ins>-?- <i>Returns</i>: <code>*this</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the 
exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s 
assignment, the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s 
assignment. The function shall not participate in overload resolution unless
<code>is_same_v&lt;decay_t&lt;U&gt;, T&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2016-08-05 Chicago LWG]</i></p>

<p>
Ville provides revised wording, that also fixes LWG <a href="lwg-defects.html#2753" title="Optional's constructors and assignments need constraints (Status: Resolved)">2753</a><sup><a href="https://cplusplus.github.io/LWG/issue2753" title="Latest snapshot">(i)</a></sup>.
<p/>
Rationale:
</p>
<ol>
<li><p>The resolution of LWG <a href="lwg-defects.html#2753" title="Optional's constructors and assignments need constraints (Status: Resolved)">2753</a><sup><a href="https://cplusplus.github.io/LWG/issue2753" title="Latest snapshot">(i)</a></sup> makes special
member functions defined as deleted in case the desired
constraints aren't met.</p></li>
<li><p>There is no decay for the converting
constructor <code>optional(U&amp;&amp;)</code>, there is a <code>remove_reference</code> instead.
The target type may hold a <i>cv</i>-qualified type, and the incoming
type may hold a <i>cv</i>-qualified type, but neither can hold a reference.
Thus, <code>remove_reference</code> is what we need, <code>remove_cv</code> would
be wrong, and <code>decay</code> would be wrong.</p></li>
<li><p>There is no <code>decay</code> or <code>remove_reference</code> for converting constructors like
<code>optional(optional&lt;U&gt;)</code>, because none is needed.</p></li>
<li><p>For <code>optional(U&amp;&amp;)</code>, an added constraint is that <code>U</code> is
not a specialization of <code>optional</code></p></li>
</ol>

<p><i>[2016-08, Chicago]</i></p>

<p>Fri PM: Move to Tentatively Ready</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to N4606.</p>

<ol>
<li><p>Modify 22.5.3 <a href="https://wg21.link/optional.optional">[optional.optional]</a> as indicated:</p>

<blockquote>
<pre>
template &lt;class T&gt; class optional
{
public:
  using value_type = T;
  
  <i>// 20.6.3.1, Constructors</i>
  constexpr optional() noexcept;
  constexpr optional(nullopt_t) noexcept;
  optional(const optional &amp;);
  optional(optional &amp;&amp;) noexcept(<i>see below</i>);
  constexpr optional(const T &amp;);
  constexpr optional(T &amp;&amp;);
  template &lt;class... Args&gt; constexpr explicit optional(in_place_t, Args &amp;&amp;...);
  template &lt;class U, class... Args&gt;
    constexpr explicit optional(in_place_t, initializer_list&lt;U&gt;, Args &amp;&amp;...);
  <ins>template &lt;class U&gt; <em>EXPLICIT</em> constexpr optional(U &amp;&amp;);
  template &lt;class U&gt; <em>EXPLICIT</em> optional(const optional&lt;U&gt; &amp;);
  template &lt;class U&gt; <em>EXPLICIT</em> optional(optional&lt;U&gt; &amp;&amp;);</ins>
  
  [&hellip;]
  
  <i>// 20.6.3.3, Assignment</i>
  optional &amp;operator=(nullopt_t) noexcept;
  optional &amp;operator=(const optional &amp;);
  optional &amp;operator=(optional &amp;&amp;) noexcept(<i>see below</i>);
  template &lt;class U&gt; optional &amp;operator=(U &amp;&amp;);
  <ins>template &lt;class U&gt; optional&amp; operator=(const optional&lt;U&gt; &amp;);
  template &lt;class U&gt; optional&amp; operator=(optional&lt;U&gt; &amp;&amp;);</ins>
  template &lt;class... Args&gt; void emplace(Args &amp;&amp;...);
  template &lt;class U, class... Args&gt;
    void emplace(initializer_list&lt;U&gt;, Args &amp;&amp;...);

  [&hellip;]
  
};
</pre>
</blockquote>
</li>

<li><p>Change  [optional.object.ctor] as indicated:</p>

<blockquote>
<pre>
optional(const optional&lt;T&gt;&amp; rhs);
</pre>
<blockquote>
<p>
<del>-3- <i>Requires:</i> <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
<ins>-?- <i>Remarks:</i> This constructor shall be defined as deleted
unless <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
optional(optional&lt;T&gt;&amp;&amp; rhs) noexcept(<i>see below</i>);
</pre>
<blockquote>
<p>
<del>-7- <i>Requires:</i> <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-11- <i>Remarks:</i> The expression inside <code>noexcept</code> is equivalent to <code>is_nothrow_move_constructible_v&lt;T&gt;</code>.
<ins>This constructor shall be defined as deleted unless <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
constexpr optional(const T&amp; v);
</pre>
<blockquote>
<p>
<del>-12- <i>Requires:</i> <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-16- <i>Remarks:</i> If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be 
a <code>constexpr</code> constructor. <ins>This constructor shall not participate in overload
resolution unless <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
constexpr optional(T&amp;&amp; v);
</pre>
<blockquote>
<p>
<del>-17- <i>Requires:</i> <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-21- <i>Remarks:</i> If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be 
a <code>constexpr</code> constructor. <ins>This constructor shall not participate in overload
resolution unless <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
template &lt;class... Args&gt; constexpr explicit optional(in_place_t, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
<del>-22- <i>Requires:</i> <code>is_constructible_v&lt;T, Args&amp;&amp;...&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-26- <i>Remarks:</i> If <code>T</code>'s constructor selected for the initialization is a <code>constexpr</code> constructor, 
this constructor shall be a <code>constexpr</code> constructor. <ins>This constructor shall not participate in overload
resolution unless <code>is_constructible_v&lt;T, Args...&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
template &lt;class U, class... Args&gt;
  constexpr explicit optional(in_place_t, initializer_list&lt;U&gt; il, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
<del>-27- <i>Requires:</i> <code>is_constructible_v&lt;T, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is 
<code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-31- <i>Remarks:</i> The <del>function</del><ins>constructor</ins> shall not participate in overload resolution unless 
<code>is_constructible_v&lt;T, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is <code>true</code>. 
If <code>T</code>'s constructor selected for the initialization is a <code>constexpr</code> constructor, this constructor 
shall be a <code>constexpr</code> constructor.
</p>
</blockquote>
<p>
<ins>[<i>Note:</i> The following constructors are conditionally specified
as explicit. This is typically implemented by declaring two such
constructors, of which at most one participates in overload
resolution. &mdash; <i>end note</i>]</ins>
</p>
<pre>
<ins>template &lt;class U&gt;
  <em>EXPLICIT</em> constexpr optional(U&amp;&amp; v);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> Initializes the contained value as if
direct-non-list-initializing an object of type <code>T</code> with the expression
<code>std::forward&lt;U&gt;(v)</code>.</ins>
<p/>
<ins>-?- <i>Postconditions:</i> <code>*this</code> contains a value.</ins>
<p/>
<ins>-?- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks:</i> If <code>T</code>'s selected constructor is a <code>constexpr</code>
constructor, this constructor shall be a <code>constexpr</code> constructor. This
constructor shall not participate in overload resolution unless
<code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is <code>true</code>, <code>remove_reference_t&lt;U&gt;</code> 
is not the same type as <code>T</code>, and <code>U</code> is not a specialization of <code>optional</code>. The
constructor is explicit if and only if <code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code> is
<code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt;
  <em>EXPLICIT</em> optional(const optional&lt;U&gt;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> If <code>rhs</code> contains a value, initializes the
contained value as if direct-non-list-initializing an object of type <code>T</code>
with the expression <code>*rhs</code>.</ins>
<p/>
<ins>-?- <i>Postconditions:</i> <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks:</i> This constructor shall not participate in
overload resolution unless <code>is_constructible_v&lt;T, const U&amp;&gt;</code> is 
<code>true</code> and <code>is_same_v&lt;U, T&gt;</code> is <code>false</code>. The constructor is 
explicit if and only if <code>is_convertible_v&lt;const U&amp;, T&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt;
  <em>EXPLICIT</em> optional(optional&lt;U&gt;&amp;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> If <code>rhs</code> contains a value, initializes the
contained value as if direct-non-list-initializing an object of type <code>T</code>
with the expression <code>std::move(*rhs)</code>. <code>bool(rhs)</code> is unchanged.</ins>
<p/>
<ins>-?- <i>Postconditions:</i> <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks:</i> This constructor shall not participate in
overload resolution unless <code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is 
<code>true</code> and <code>is_same_v&lt;U, T&gt;</code> is <code>false</code>. The constructor is 
explicit if and only if <code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>

</blockquote>
</li>

<li><p>Change  [optional.object.assign] as indicated:</p>

<blockquote>
<pre>
optional&lt;T&gt;&amp; operator=(const optional&lt;T&gt;&amp; rhs);
</pre>
<blockquote>
<p>
<del>-4- <i>Requires:</i> <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code> and 
<code>is_copy_assignable_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-8- <i>Remarks:</i> If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged.
If an exception is thrown during the call to <code>T</code>'s copy constructor, no effect. If an exception is thrown
during the call to <code>T</code>'s copy assignment, the state of its contained value is as defined by the exception
safety guarantee of <code>T</code>'s copy assignment. <ins>This operator shall be defined as deleted unless
<code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code> and <code>is_copy_assignable_v&lt;T&gt;</code> is
<code>true</code>.</ins>
</p>
</blockquote>
<pre>
optional&lt;T&gt;&amp; operator=(optional&lt;T&gt;&amp;&amp; rhs) noexcept(<i>see below</i>);
</pre>
<blockquote>
<p>
<del>-9- <i>Requires:</i> <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code> and 
<code>is_move_assignable_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-13- <i>Remarks:</i> The expression inside <code>noexcept</code> is equivalent to:
</p>
<blockquote><pre>
is_nothrow_move_assignable_v&lt;T&gt; &amp;&amp; is_nothrow_move_constructible_v&lt;T&gt;
</pre></blockquote>
<p>
-14- If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s move constructor, the state of <code>*rhs.val</code> 
is determined by the exception safety guarantee of <code>T</code>'s move constructor. If an exception is 
thrown during the call to <code>T</code>'s move assignment, the state of <code>*val</code> and <code>*rhs.val</code> 
is determined by the exception safety guarantee of <code>T</code>'s move assignment. <ins>This operator 
shall be defined as deleted unless <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code> and 
<code>is_move_assignable_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(U&amp;&amp; v);
</pre>
<blockquote>
<p>
<del>-15- <i>Requires:</i> <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code> and 
<code>is_assignable_v&lt;T&amp;, U&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-19- <i>Remarks:</i> If any exception is thrown, the result of the expression <code>bool(*this)</code> 
remains unchanged. If an exception is thrown during the call to <code>T</code>'s constructor, the state 
of <code>v</code> is determined by the exception safety guarantee of <code>T</code>'s constructor. If an 
exception is thrown during the call to <code>T</code>'s assignment, the state of <code>*val</code> and <code>v</code> 
is determined by the exception safety guarantee of <code>T</code>'s assignment. <del>The</del><ins>This</ins> function
shall not participate in overload resolution unless <del><code>is_same_v&lt;decay_t&lt;U&gt;, T&gt;</code></del> 
<ins><code>decay_t&lt;U&gt;</code> is not <code>nullopt_t</code>, <code>decay_t&lt;U&gt;</code> is not a specialization of 
<code>optional</code>, <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code> and <code>is_assignable_v&lt;T&amp;, 
U&gt;</code></ins> is <code>true</code>.
<p/>
<del>-20- <i>Notes:</i> The reason for providing such generic assignment and then constraining it so that effectively 
<code>T == U</code> is to guarantee that assignment of the form <code>o = {}</code> is unambiguous.</del>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(const optional&lt;U&gt;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>:</ins>
</p>
<table border="1">
<caption><ins>Table ? &mdash; <code>optional::operator=(const optional&lt;U&gt;&amp;)</code> effects</ins></caption>

<tr>
<th></th>
<th><ins><b><code>*this</code> contains a value</b></ins></th>
<th><ins><b><code>*this</code> does not contain a value</b></ins></th>
</tr>

<tr>
<td><ins><b><code>rhs</code> contains a value</b></ins></td>
<td><ins>assigns <code>*rhs</code> to the contained value</ins></td>
<td><ins>initializes the contained value as if direct-non-list-initializing an object of type 
<code>T</code> with <code>*rhs</code></ins></td>
</tr>

<tr>
<td><ins><b><code>rhs</code> does not contain a value</b></ins></td>
<td><ins>destroys the contained value by calling <code>val-&gt;T::~T()</code></ins></td>
<td><ins>no effect</ins></td>
</tr>

</table> 
<p>
<ins>-?- <i>Returns</i>: <code>*this</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the 
exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s assignment, 
the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s assignment. 
The function shall not participate in overload resolution unless <code>is_constructible_v&lt;T, const U&amp;&gt;</code> is 
<code>true</code> and <code>is_assignable_v&lt;T&amp;, const U&amp;&gt;</code> is <code>true</code> and <code>is_same_v&lt;U, T&gt;</code> 
is <code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(optional&lt;U&gt;&amp;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: The result of the expression <code>bool(rhs)</code> remains unchanged. </ins>
</p>
<table border="1">
<caption><ins>Table ? &mdash; <code>optional::operator=(optional&lt;U&gt;&amp;&amp;)</code> effects</ins></caption>

<tr>
<th></th>
<th><ins><b><code>*this</code> contains a value</b></ins></th>
<th><ins><b><code>*this</code> does not contain a value</b></ins></th>
</tr>

<tr>
<td><ins><b><code>rhs</code> contains a value</b></ins></td>
<td><ins>assigns <code>std::move(*rhs)</code> to the contained value</ins></td>
<td><ins>initializes the contained value as if direct-non-list-initializing an object of type 
<code>T</code> with <code>std::move(*rhs)</code></ins></td>
</tr>

<tr>
<td><ins><b><code>rhs</code> does not contain a value</b></ins></td>
<td><ins>destroys the contained value by calling <code>val-&gt;T::~T()</code></ins></td>
<td><ins>no effect</ins></td>
</tr>

</table> 
<p>
<ins>-?- <i>Returns</i>: <code>*this</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the 
exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s 
assignment, the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s 
assignment. The function shall not participate in overload resolution unless <code>is_constructible_v&lt;T, U&gt;</code> is 
<code>true</code> and <code>is_assignable_v&lt;T&amp;, U&gt;</code> is <code>true</code> and <code>is_same_v&lt;U, T&gt;</code> is 
<code>false</code>.</ins>
</p>
</blockquote>

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

<p><i>[2016-08-08 Ville reopens and provides improved wording]</i></p>

<p>
This alternative proposed wording also resolves <a href="lwg-defects.html#2753" title="Optional's constructors and assignments need constraints (Status: Resolved)">2753</a><sup><a href="https://cplusplus.github.io/LWG/issue2753" title="Latest snapshot">(i)</a></sup>.
<p/>
The constructors that take a const <code>T&amp;</code> or <code>T&amp;&amp;</code> are replaced by 
a constructor template that takes a <code>U&amp;&amp;</code> and defaults <code>U = T</code>. This 
allows copy-list-initialization with empty braces to still work:
</p>
<blockquote><pre>
optional&lt;<em>whatever</em>&gt; o = {}; <i>// equivalent to initializing <code>optional</code> with <code>nullopt</code></i>
</pre></blockquote>
<p>
This resolution makes converting constructors and assignments have the same capabilities, including 
using arguments that can't be deduced. That is achieved by using a perfect-forwarding constructor
and an assignment operator that default their argument to <code>T</code>. We don't need separate 
overloads for <code>T</code>, the overload for <code>U</code> does the job:
</p>
<blockquote><pre>
optional&lt;vector&lt;int&gt;&gt; ovi{{1, 2, 3}}; // still works
ovi = {4, 5, 6, 7}; // now works, didn't work before
</pre></blockquote>
<p>
Furthermore, this proposed wording makes <code>optional</code> "always unwrap". That is, the result 
of the following initializations is the same:
</p>
<blockquote><pre>
optional&lt;optional&lt;int&gt;&gt; oi = optional&lt;int&gt;();
optional&lt;optional&lt;int&gt;&gt; oi = optional&lt;short&gt;();
</pre></blockquote>
<p>
Both of those initializations initialize the <code>optional</code> wrapping
another <code>optional</code> as if initializing with <code>nullopt</code>. Assignments
do the same. These changes solve the issues pointed out by Tomasz Kami&nacute;ski.
<p/>
This P/R has been implemented and tested as a modification on top of libstdc++'s <code>optional</code>.
</p>

<p><i>[2016-08-08 Ville and Tomasz collaborate and improve wording]</i></p>

<p>
The suggested wording retains <code>optional</code>'s converting constructors and assignment
operators, but provides sane results for the types Tomasz Kaminski depicts
in previous discussions.
<p/>
As opposed to the current P/R of this issue, which does "always unwrap",
this P/R does "always value-forward unless the incoming type is exactly
a type that a special member function takes by reference, and don't
unwrap if a value-forwarder can take an optional by any kind of reference".
<p/>
I and Tomasz believe this is the best compromise between the different
desires, and thus the best outcome so far.
<p/>
This P/R has been implemented and tested on libstdc++.
</p>

<p><i>[2016-09-08 Casey Carter finetunes existing resolution for move members]</i></p>


<p><i>[2016-09-09 Issues Resolution Telecon]</i></p>

<p>Move to Tentatively Ready</p>

<p><i>[2016-10-06 Ville Voutilainen finetunes the resolution for assignment from scalars]</i></p>


<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to N4606.</p>

<ol>
<li><p>Modify 22.5.3 <a href="https://wg21.link/optional.optional">[optional.optional]</a> as indicated:</p>

<blockquote>
<pre>
template &lt;class T&gt; class optional
{
public:
  using value_type = T;
  
  <i>// 20.6.3.1, Constructors</i>
  constexpr optional() noexcept;
  constexpr optional(nullopt_t) noexcept;
  optional(const optional &amp;);
  optional(optional &amp;&amp;) noexcept(<i>see below</i>);
  <del>constexpr optional(const T &amp;);</del>
  <del>constexpr optional(T &amp;&amp;);</del>
  template &lt;class... Args&gt; constexpr explicit optional(in_place_t, Args &amp;&amp;...);
  template &lt;class U, class... Args&gt;
    constexpr explicit optional(in_place_t, initializer_list&lt;U&gt;, Args &amp;&amp;...);
  <ins>template &lt;class U = T&gt; <em>EXPLICIT</em> constexpr optional(U &amp;&amp;);
  template &lt;class U&gt; <em>EXPLICIT</em> optional(const optional&lt;U&gt; &amp;);
  template &lt;class U&gt; <em>EXPLICIT</em> optional(optional&lt;U&gt; &amp;&amp;);</ins>
  
  [&hellip;]
  
  <i>// 20.6.3.3, Assignment</i>
  optional &amp;operator=(nullopt_t) noexcept;
  optional &amp;operator=(const optional &amp;);
  optional &amp;operator=(optional &amp;&amp;) noexcept(<i>see below</i>);
  template &lt;class U <ins>= T</ins>&gt; optional &amp;operator=(U &amp;&amp;);
  <ins>template &lt;class U&gt; optional&amp; operator=(const optional&lt;U&gt; &amp;);
  template &lt;class U&gt; optional&amp; operator=(optional&lt;U&gt; &amp;&amp;);</ins>
  template &lt;class... Args&gt; void emplace(Args &amp;&amp;...);
  template &lt;class U, class... Args&gt;
    void emplace(initializer_list&lt;U&gt;, Args &amp;&amp;...);

  [&hellip;]
  
};
</pre>
</blockquote>
</li>

<li><p>Change  [optional.object.ctor] as indicated:</p>

<blockquote>
<pre>
optional(const optional&lt;T&gt;&amp; rhs);
</pre>
<blockquote>
<p>
<del>-3- <i>Requires:</i> <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
<ins>-?- <i>Remarks:</i> This constructor shall be defined as deleted
unless <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
optional(optional&lt;T&gt;&amp;&amp; rhs) noexcept(<i>see below</i>);
</pre>
<blockquote>
<p>
<del>-7- <i>Requires:</i> <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-11- <i>Remarks:</i> The expression inside <code>noexcept</code> is equivalent to <code>is_nothrow_move_constructible_v&lt;T&gt;</code>.
<ins>This constructor shall not participate in overload resolution unless <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
<del>constexpr optional(const T&amp; v);</del>
</pre>
<blockquote>
<p>
<del>-12- <i>Requires:</i> <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
<del>-13- <i>Effects:</i> Initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> 
with the expression <code>v</code>.</del>
<p/>
<del>-14- <i>Postcondition:</i> <code>*this</code> contains a value.</del>
<p/>
<del>-15- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</del>
<p/>
<del>-16- <i>Remarks:</i> If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be 
a <code>constexpr</code> constructor.</del>
</p>
</blockquote>
<pre>
<del>constexpr optional(T&amp;&amp; v);</del>
</pre>
<blockquote>
<p>
<del>-17- <i>Requires:</i> <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
<del>-18- <i>Effects:</i> Initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> 
with the expression <code>std::move(v)</code>.</del>
<p/>
<del>-19- <i>Postcondition:</i> <code>*this</code> contains a value.</del>
<p/>
<del>-20- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</del>
<p/>
<del>-21- <i>Remarks:</i> If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be 
a <code>constexpr</code> constructor.</del>
</p>
</blockquote>
<pre>
template &lt;class... Args&gt; constexpr explicit optional(in_place_t, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
<del>-22- <i>Requires:</i> <code>is_constructible_v&lt;T, Args&amp;&amp;...&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-26- <i>Remarks:</i> If <code>T</code>'s constructor selected for the initialization is a <code>constexpr</code> constructor, 
this constructor shall be a <code>constexpr</code> constructor. <ins>This constructor shall not participate in overload
resolution unless <code>is_constructible_v&lt;T, Args...&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
template &lt;class U, class... Args&gt;
  constexpr explicit optional(in_place_t, initializer_list&lt;U&gt; il, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
<del>-27- <i>Requires:</i> <code>is_constructible_v&lt;T, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is 
<code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-31- <i>Remarks:</i> <del>The function</del><ins>This constructor</ins> shall not participate in overload resolution unless 
<code>is_constructible_v&lt;T, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is <code>true</code>. 
If <code>T</code>'s constructor selected for the initialization is a <code>constexpr</code> constructor, this constructor 
shall be a <code>constexpr</code> constructor.
</p>
</blockquote>
<p>
<ins>[<i>Note:</i> The following constructors are conditionally specified
as explicit. This is typically implemented by declaring two such
constructors, of which at most one participates in overload
resolution. &mdash; <i>end note</i>]</ins>
</p>
<pre>
<ins>template &lt;class U = T&gt;
  <em>EXPLICIT</em> constexpr optional(U&amp;&amp; v);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> Initializes the contained value as if
direct-non-list-initializing an object of type <code>T</code> with the expression
<code>std::forward&lt;U&gt;(v)</code>.</ins>
<p/>
<ins>-?- <i>Postconditions:</i> <code>*this</code> contains a value.</ins>
<p/>
<ins>-?- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks:</i> If <code>T</code>'s selected constructor is a <code>constexpr</code>
constructor, this constructor shall be a <code>constexpr</code> constructor. This
constructor shall not participate in overload resolution unless
<code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is <code>true</code>, <code>is_same_v&lt;U, 
in_place_t&gt;</code> is <code>false</code>, and <code>is_same_v&lt;optional&lt;T&gt;, decay_t&lt;U&gt;&gt;</code> 
is <code>false</code>. The constructor is explicit if and only if 
<code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt;
  <em>EXPLICIT</em> optional(const optional&lt;U&gt;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> If <code>rhs</code> contains a value, initializes the
contained value as if direct-non-list-initializing an object of type <code>T</code>
with the expression <code>*rhs</code>.</ins>
<p/>
<ins>-?- <i>Postconditions:</i> <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks:</i> This constructor shall not participate in
overload resolution unless <code>is_constructible_v&lt;T, const U&amp;&gt;</code> is <code>true</code>, 
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
and <code>is_convertible_v&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>. 
The constructor is explicit if and only if <code>is_convertible_v&lt;const U&amp;, T&gt;</code> is 
<code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt;
  <em>EXPLICIT</em> optional(optional&lt;U&gt;&amp;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> If <code>rhs</code> contains a value, initializes the
contained value as if direct-non-list-initializing an object of type <code>T</code>
with the expression <code>std::move(*rhs)</code>. <code>bool(rhs)</code> is unchanged.</ins>
<p/>
<ins>-?- <i>Postconditions:</i> <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks:</i> This constructor shall not participate in
overload resolution unless <code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is <code>true</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
and <code>is_convertible_v&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>. The constructor 
is explicit if and only if <code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>

</blockquote>
</li>

<li><p>Change  [optional.object.assign] as indicated:</p>

<blockquote>
<pre>
optional&lt;T&gt;&amp; operator=(const optional&lt;T&gt;&amp; rhs);
</pre>
<blockquote>
<p>
<del>-4- <i>Requires:</i> <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code> and 
<code>is_copy_assignable_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-8- <i>Remarks:</i> If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged.
If an exception is thrown during the call to <code>T</code>'s copy constructor, no effect. If an exception is thrown
during the call to <code>T</code>'s copy assignment, the state of its contained value is as defined by the exception
safety guarantee of <code>T</code>'s copy assignment. <ins>This operator shall be defined as deleted unless
<code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code> and <code>is_copy_assignable_v&lt;T&gt;</code> is
<code>true</code>.</ins>
</p>
</blockquote>
<pre>
optional&lt;T&gt;&amp; operator=(optional&lt;T&gt;&amp;&amp; rhs) noexcept(<i>see below</i>);
</pre>
<blockquote>
<p>
<del>-9- <i>Requires:</i> <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code> and 
<code>is_move_assignable_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-13- <i>Remarks:</i> The expression inside <code>noexcept</code> is equivalent to:
</p>
<blockquote><pre>
is_nothrow_move_assignable_v&lt;T&gt; &amp;&amp; is_nothrow_move_constructible_v&lt;T&gt;
</pre></blockquote>
<p>
-14- If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s move constructor, the state of <code>*rhs.val</code> 
is determined by the exception safety guarantee of <code>T</code>'s move constructor. If an exception is 
thrown during the call to <code>T</code>'s move assignment, the state of <code>*val</code> and <code>*rhs.val</code> 
is determined by the exception safety guarantee of <code>T</code>'s move assignment. <ins>This operator 
shall not participate in overload resolution unless <code>is_move_constructible_v&lt;T&gt;</code> is 
<code>true</code> and <code>is_move_assignable_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
template &lt;class U <ins>= T</ins>&gt; optional&lt;T&gt;&amp; operator=(U&amp;&amp; v);
</pre>
<blockquote>
<p>
<del>-15- <i>Requires:</i> <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code> and 
<code>is_assignable_v&lt;T&amp;, U&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-19- <i>Remarks:</i> If any exception is thrown, the result of the expression <code>bool(*this)</code> 
remains unchanged. If an exception is thrown during the call to <code>T</code>'s constructor, the state 
of <code>v</code> is determined by the exception safety guarantee of <code>T</code>'s constructor. If an 
exception is thrown during the call to <code>T</code>'s assignment, the state of <code>*val</code> and <code>v</code> 
is determined by the exception safety guarantee of <code>T</code>'s assignment. <del>The</del><ins>This</ins> function
shall not participate in overload resolution unless <del><code>is_same_v&lt;decay_t&lt;U&gt;, T&gt;</code></del> 
<ins><code>is_same_v&lt;optional&lt;T&gt;, decay_t&lt;U&gt;&gt;</code> is <code>false</code>, 
<code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code>, and 
<code>is_assignable_v&lt;T&amp;, U&gt;</code></ins> is <code>true</code>.
<p/>
<del>-20- <i>Notes:</i> The reason for providing such generic assignment and then constraining it so that effectively 
<code>T == U</code> is to guarantee that assignment of the form <code>o = {}</code> is unambiguous.</del>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(const optional&lt;U&gt;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: See Table ?.</ins>
</p>
<table border="1">
<caption><ins>Table ? &mdash; <code>optional::operator=(const optional&lt;U&gt;&amp;)</code> effects</ins></caption>

<tr>
<th></th>
<th><ins><b><code>*this</code> contains a value</b></ins></th>
<th><ins><b><code>*this</code> does not contain a value</b></ins></th>
</tr>

<tr>
<td><ins><b><code>rhs</code> contains a value</b></ins></td>
<td><ins>assigns <code>*rhs</code> to the contained value</ins></td>
<td><ins>initializes the contained value as if direct-non-list-initializing an object of type 
<code>T</code> with <code>*rhs</code></ins></td>
</tr>

<tr>
<td><ins><b><code>rhs</code> does not contain a value</b></ins></td>
<td><ins>destroys the contained value by calling <code>val-&gt;T::~T()</code></ins></td>
<td><ins>no effect</ins></td>
</tr>

</table> 
<p>
<ins>-?- <i>Returns</i>: <code>*this</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the 
exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s assignment, 
the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s assignment. 
This function shall not participate in overload resolution unless <code>is_constructible_v&lt;T, const U&amp;&gt;</code> is 
<code>true</code>, <code>is_assignable_v&lt;T&amp;, const U&amp;&gt;</code> is <code>true</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
and <code>is_assignable_v&lt;T&amp;, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(optional&lt;U&gt;&amp;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: See Table ?. The result of the expression <code>bool(rhs)</code> remains unchanged. </ins>
</p>
<table border="1">
<caption><ins>Table ? &mdash; <code>optional::operator=(optional&lt;U&gt;&amp;&amp;)</code> effects</ins></caption>

<tr>
<th></th>
<th><ins><b><code>*this</code> contains a value</b></ins></th>
<th><ins><b><code>*this</code> does not contain a value</b></ins></th>
</tr>

<tr>
<td><ins><b><code>rhs</code> contains a value</b></ins></td>
<td><ins>assigns <code>std::move(*rhs)</code> to the contained value</ins></td>
<td><ins>initializes the contained value as if direct-non-list-initializing an object of type 
<code>T</code> with <code>std::move(*rhs)</code></ins></td>
</tr>

<tr>
<td><ins><b><code>rhs</code> does not contain a value</b></ins></td>
<td><ins>destroys the contained value by calling <code>val-&gt;T::~T()</code></ins></td>
<td><ins>no effect</ins></td>
</tr>

</table> 
<p>
<ins>-?- <i>Returns</i>: <code>*this</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the 
exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s 
assignment, the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s 
assignment. This function shall not participate in overload resolution unless <code>is_constructible_v&lt;T, U&gt;</code> is 
<code>true</code>, <code>is_assignable_v&lt;T&amp;, U&gt;</code> is <code>true</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible&lt;const optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
and <code>is_assignable_v&lt;T&amp;, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>

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

</blockquote>
  


<p id="res-2756"><b>Proposed resolution:</b></p>
<p>This wording is relative to N4606.</p>

<ol>
<li><p>Modify 22.5.3 <a href="https://wg21.link/optional.optional">[optional.optional]</a> as indicated:</p>

<blockquote>
<pre>
template &lt;class T&gt; class optional
{
public:
  using value_type = T;
  
  <i>// 20.6.3.1, Constructors</i>
  constexpr optional() noexcept;
  constexpr optional(nullopt_t) noexcept;
  optional(const optional &amp;);
  optional(optional &amp;&amp;) noexcept(<i>see below</i>);
  <del>constexpr optional(const T &amp;);</del>
  <del>constexpr optional(T &amp;&amp;);</del>
  template &lt;class... Args&gt; constexpr explicit optional(in_place_t, Args &amp;&amp;...);
  template &lt;class U, class... Args&gt;
    constexpr explicit optional(in_place_t, initializer_list&lt;U&gt;, Args &amp;&amp;...);
  <ins>template &lt;class U = T&gt; <em>EXPLICIT</em> constexpr optional(U &amp;&amp;);
  template &lt;class U&gt; <em>EXPLICIT</em> optional(const optional&lt;U&gt; &amp;);
  template &lt;class U&gt; <em>EXPLICIT</em> optional(optional&lt;U&gt; &amp;&amp;);</ins>
  
  [&hellip;]
  
  <i>// 20.6.3.3, Assignment</i>
  optional &amp;operator=(nullopt_t) noexcept;
  optional &amp;operator=(const optional &amp;);
  optional &amp;operator=(optional &amp;&amp;) noexcept(<i>see below</i>);
  template &lt;class U <ins>= T</ins>&gt; optional &amp;operator=(U &amp;&amp;);
  <ins>template &lt;class U&gt; optional&amp; operator=(const optional&lt;U&gt; &amp;);
  template &lt;class U&gt; optional&amp; operator=(optional&lt;U&gt; &amp;&amp;);</ins>
  template &lt;class... Args&gt; void emplace(Args &amp;&amp;...);
  template &lt;class U, class... Args&gt;
    void emplace(initializer_list&lt;U&gt;, Args &amp;&amp;...);

  [&hellip;]
  
};
</pre>
</blockquote>
</li>

<li><p>Change  [optional.object.ctor] as indicated:</p>

<blockquote>
<pre>
optional(const optional&lt;T&gt;&amp; rhs);
</pre>
<blockquote>
<p>
<del>-3- <i>Requires:</i> <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
<ins>-?- <i>Remarks:</i> This constructor shall be defined as deleted
unless <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
optional(optional&lt;T&gt;&amp;&amp; rhs) noexcept(<i>see below</i>);
</pre>
<blockquote>
<p>
<del>-7- <i>Requires:</i> <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-11- <i>Remarks:</i> The expression inside <code>noexcept</code> is equivalent to <code>is_nothrow_move_constructible_v&lt;T&gt;</code>.
<ins>This constructor shall not participate in overload resolution unless <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
<del>constexpr optional(const T&amp; v);</del>
</pre>
<blockquote>
<p>
<del>-12- <i>Requires:</i> <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
<del>-13- <i>Effects:</i> Initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> 
with the expression <code>v</code>.</del>
<p/>
<del>-14- <i>Postcondition:</i> <code>*this</code> contains a value.</del>
<p/>
<del>-15- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</del>
<p/>
<del>-16- <i>Remarks:</i> If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be 
a <code>constexpr</code> constructor.</del>
</p>
</blockquote>
<pre>
<del>constexpr optional(T&amp;&amp; v);</del>
</pre>
<blockquote>
<p>
<del>-17- <i>Requires:</i> <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
<del>-18- <i>Effects:</i> Initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> 
with the expression <code>std::move(v)</code>.</del>
<p/>
<del>-19- <i>Postcondition:</i> <code>*this</code> contains a value.</del>
<p/>
<del>-20- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</del>
<p/>
<del>-21- <i>Remarks:</i> If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be 
a <code>constexpr</code> constructor.</del>
</p>
</blockquote>
<pre>
template &lt;class... Args&gt; constexpr explicit optional(in_place_t, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
<del>-22- <i>Requires:</i> <code>is_constructible_v&lt;T, Args&amp;&amp;...&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-26- <i>Remarks:</i> If <code>T</code>'s constructor selected for the initialization is a <code>constexpr</code> constructor, 
this constructor shall be a <code>constexpr</code> constructor. <ins>This constructor shall not participate in overload
resolution unless <code>is_constructible_v&lt;T, Args...&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
template &lt;class U, class... Args&gt;
  constexpr explicit optional(in_place_t, initializer_list&lt;U&gt; il, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
<del>-27- <i>Requires:</i> <code>is_constructible_v&lt;T, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is 
<code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-31- <i>Remarks:</i> <del>The function</del><ins>This constructor</ins> shall not participate in overload resolution unless 
<code>is_constructible_v&lt;T, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is <code>true</code>. 
If <code>T</code>'s constructor selected for the initialization is a <code>constexpr</code> constructor, this constructor 
shall be a <code>constexpr</code> constructor.
</p>
</blockquote>
<p>
<ins>[<i>Note:</i> The following constructors are conditionally specified
as explicit. This is typically implemented by declaring two such
constructors, of which at most one participates in overload
resolution. &mdash; <i>end note</i>]</ins>
</p>
<pre>
<ins>template &lt;class U = T&gt;
  <em>EXPLICIT</em> constexpr optional(U&amp;&amp; v);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> Initializes the contained value as if
direct-non-list-initializing an object of type <code>T</code> with the expression
<code>std::forward&lt;U&gt;(v)</code>.</ins>
<p/>
<ins>-?- <i>Postconditions:</i> <code>*this</code> contains a value.</ins>
<p/>
<ins>-?- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks:</i> If <code>T</code>'s selected constructor is a <code>constexpr</code>
constructor, this constructor shall be a <code>constexpr</code> constructor. This
constructor shall not participate in overload resolution unless
<code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is <code>true</code>, <code>is_same_v&lt;U, 
in_place_t&gt;</code> is <code>false</code>, and <code>is_same_v&lt;optional&lt;T&gt;, decay_t&lt;U&gt;&gt;</code> 
is <code>false</code>. The constructor is explicit if and only if 
<code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt;
  <em>EXPLICIT</em> optional(const optional&lt;U&gt;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> If <code>rhs</code> contains a value, initializes the
contained value as if direct-non-list-initializing an object of type <code>T</code>
with the expression <code>*rhs</code>.</ins>
<p/>
<ins>-?- <i>Postconditions:</i> <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks:</i> This constructor shall not participate in
overload resolution unless <code>is_constructible_v&lt;T, const U&amp;&gt;</code> is <code>true</code>, 
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
and <code>is_convertible_v&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>. 
The constructor is explicit if and only if <code>is_convertible_v&lt;const U&amp;, T&gt;</code> is 
<code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt;
  <em>EXPLICIT</em> optional(optional&lt;U&gt;&amp;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> If <code>rhs</code> contains a value, initializes the
contained value as if direct-non-list-initializing an object of type <code>T</code>
with the expression <code>std::move(*rhs)</code>. <code>bool(rhs)</code> is unchanged.</ins>
<p/>
<ins>-?- <i>Postconditions:</i> <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Throws:</i> Any exception thrown by the selected constructor of <code>T</code>.</ins>
<p/>
<ins>-?- <i>Remarks:</i> This constructor shall not participate in
overload resolution unless <code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is <code>true</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
and <code>is_convertible_v&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>. The constructor 
is explicit if and only if <code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>

</blockquote>
</li>

<li><p>Change  [optional.object.assign] as indicated:</p>

<blockquote>
<pre>
optional&lt;T&gt;&amp; operator=(const optional&lt;T&gt;&amp; rhs);
</pre>
<blockquote>
<p>
<del>-4- <i>Requires:</i> <code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code> and 
<code>is_copy_assignable_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-8- <i>Remarks:</i> If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged.
If an exception is thrown during the call to <code>T</code>'s copy constructor, no effect. If an exception is thrown
during the call to <code>T</code>'s copy assignment, the state of its contained value is as defined by the exception
safety guarantee of <code>T</code>'s copy assignment. <ins>This operator shall be defined as deleted unless
<code>is_copy_constructible_v&lt;T&gt;</code> is <code>true</code> and <code>is_copy_assignable_v&lt;T&gt;</code> is
<code>true</code>.</ins>
</p>
</blockquote>
<pre>
optional&lt;T&gt;&amp; operator=(optional&lt;T&gt;&amp;&amp; rhs) noexcept(<i>see below</i>);
</pre>
<blockquote>
<p>
<del>-9- <i>Requires:</i> <code>is_move_constructible_v&lt;T&gt;</code> is <code>true</code> and 
<code>is_move_assignable_v&lt;T&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-13- <i>Remarks:</i> The expression inside <code>noexcept</code> is equivalent to:
</p>
<blockquote><pre>
is_nothrow_move_assignable_v&lt;T&gt; &amp;&amp; is_nothrow_move_constructible_v&lt;T&gt;
</pre></blockquote>
<p>
-14- If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s move constructor, the state of <code>*rhs.val</code> 
is determined by the exception safety guarantee of <code>T</code>'s move constructor. If an exception is 
thrown during the call to <code>T</code>'s move assignment, the state of <code>*val</code> and <code>*rhs.val</code> 
is determined by the exception safety guarantee of <code>T</code>'s move assignment. <ins>This operator 
shall not participate in overload resolution unless <code>is_move_constructible_v&lt;T&gt;</code> is 
<code>true</code> and <code>is_move_assignable_v&lt;T&gt;</code> is <code>true</code>.</ins>
</p>
</blockquote>
<pre>
template &lt;class U <ins>= T</ins>&gt; optional&lt;T&gt;&amp; operator=(U&amp;&amp; v);
</pre>
<blockquote>
<p>
<del>-15- <i>Requires:</i> <code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code> and 
<code>is_assignable_v&lt;T&amp;, U&gt;</code> is <code>true</code>.</del>
<p/>
[&hellip;]
<p/>
-19- <i>Remarks:</i> If any exception is thrown, the result of the expression <code>bool(*this)</code> 
remains unchanged. If an exception is thrown during the call to <code>T</code>'s constructor, the state 
of <code>v</code> is determined by the exception safety guarantee of <code>T</code>'s constructor. If an 
exception is thrown during the call to <code>T</code>'s assignment, the state of <code>*val</code> and <code>v</code> 
is determined by the exception safety guarantee of <code>T</code>'s assignment. <del>The</del><ins>This</ins> function
shall not participate in overload resolution unless <del><code>is_same_v&lt;decay_t&lt;U&gt;, T&gt;</code></del> 
<ins><code>is_same_v&lt;optional&lt;T&gt;, decay_t&lt;U&gt;&gt;</code> is <code>false</code>,
conjunction_v&lt;is_scalar&lt;T&gt;, is_same&lt;T, decay_t&lt;U&gt;&gt;&gt; is <code>false</code>,
<code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code>, and 
<code>is_assignable_v&lt;T&amp;, U&gt;</code></ins> is <code>true</code>.
<p/>
<del>-20- <i>Notes:</i> The reason for providing such generic assignment and then constraining it so that effectively 
<code>T == U</code> is to guarantee that assignment of the form <code>o = {}</code> is unambiguous.</del>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(const optional&lt;U&gt;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: See Table ?.</ins>
</p>
<table border="1">
<caption><ins>Table ? &mdash; <code>optional::operator=(const optional&lt;U&gt;&amp;)</code> effects</ins></caption>

<tr>
<th></th>
<th><ins><b><code>*this</code> contains a value</b></ins></th>
<th><ins><b><code>*this</code> does not contain a value</b></ins></th>
</tr>

<tr>
<td><ins><b><code>rhs</code> contains a value</b></ins></td>
<td><ins>assigns <code>*rhs</code> to the contained value</ins></td>
<td><ins>initializes the contained value as if direct-non-list-initializing an object of type 
<code>T</code> with <code>*rhs</code></ins></td>
</tr>

<tr>
<td><ins><b><code>rhs</code> does not contain a value</b></ins></td>
<td><ins>destroys the contained value by calling <code>val-&gt;T::~T()</code></ins></td>
<td><ins>no effect</ins></td>
</tr>

</table> 
<p>
<ins>-?- <i>Returns</i>: <code>*this</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the 
exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s assignment, 
the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s assignment. 
This function shall not participate in overload resolution unless <code>is_constructible_v&lt;T, const U&amp;&gt;</code> is 
<code>true</code>, <code>is_assignable_v&lt;T&amp;, const U&amp;&gt;</code> is <code>true</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
and <code>is_assignable_v&lt;T&amp;, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>
<pre>
<ins>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(optional&lt;U&gt;&amp;&amp; rhs);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects</i>: See Table ?. The result of the expression <code>bool(rhs)</code> remains unchanged. </ins>
</p>
<table border="1">
<caption><ins>Table ? &mdash; <code>optional::operator=(optional&lt;U&gt;&amp;&amp;)</code> effects</ins></caption>

<tr>
<th></th>
<th><ins><b><code>*this</code> contains a value</b></ins></th>
<th><ins><b><code>*this</code> does not contain a value</b></ins></th>
</tr>

<tr>
<td><ins><b><code>rhs</code> contains a value</b></ins></td>
<td><ins>assigns <code>std::move(*rhs)</code> to the contained value</ins></td>
<td><ins>initializes the contained value as if direct-non-list-initializing an object of type 
<code>T</code> with <code>std::move(*rhs)</code></ins></td>
</tr>

<tr>
<td><ins><b><code>rhs</code> does not contain a value</b></ins></td>
<td><ins>destroys the contained value by calling <code>val-&gt;T::~T()</code></ins></td>
<td><ins>no effect</ins></td>
</tr>

</table> 
<p>
<ins>-?- <i>Returns</i>: <code>*this</code>.</ins>
<p/>
<ins>-?- <i>Postconditions</i>: <code>bool(rhs) == bool(*this)</code>.</ins>
<p/>
<ins>-?- <i>Remarks</i>: If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. 
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the 
exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s 
assignment, the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s 
assignment. This function shall not participate in overload resolution unless <code>is_constructible_v&lt;T, U&gt;</code> is 
<code>true</code>, <code>is_assignable_v&lt;T&amp;, U&gt;</code> is <code>true</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible&lt;const optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
<code>is_convertible&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code>,
<code>is_assignable_v&lt;T&amp;, const optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>,
and <code>is_assignable_v&lt;T&amp;, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code>.</ins>
</p>
</blockquote>

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





</body>
</html>
