<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Mon, 31 Mar 2025 at 22:33, Stewart Becker via Std-Proposals &lt;<a href="mailto:std-proposals@lists.isocpp.org">std-proposals@lists.isocpp.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>

  
    
  
  <div>
    <p>Thank you, Jonathan, for your insights. <br>
    </p>
    <div>On 31/03/2025 09:42, Jonathan Wakely
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div class="gmail_quote">
          <div>std::optional&lt;T&amp;&gt; is explicitly not allowing
            rvalue references, I don&#39;t see the committee going the other
            way for std::expected.</div>
        </div>
      </div>
    </blockquote>
    <p>Maybe I missed something, but P2988 doesn&#39;t seem to mention
      rvalue references, neither proposing nor actively disallowing
      them.  Has there been any discussion on
      std::optional&lt;T&amp;&amp;&gt; at all, or it simply not (yet)
      proposed?</p></div></blockquote><div><br></div><div> P2988R6 included a partial specialization for optional&lt;T&amp;&amp;&gt;, but P2988R7 dropped it again. The paper doesn&#39;t say why, and the minutes are vague. I thought it had been discussed and rejected, but it seems that it was just dropped so that the optional&lt;T&amp;&gt; form could make progress without getting coupled to a more novel specialization that hasn&#39;t been properly designed yet.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><p>  P2988&#39;s given rationale for optional&lt;T&amp;&gt; is
      that any type that std::tuple accepts should work with
      std::variant (and by extension, work with std::optional and
      std::expected).  As std::tuple supports both lvalue and rvalue
      references, perhaps allowing rvalue references for both
      std::optional and std::expected (and std::variant?) is a potential
      next step. <br>
    </p>
    <p><br>
    </p>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_quote">
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div>
              <ol>
                <li>std::exception_ptr::value() called
                  std::rethrow_exception(error()) rather than throwing a
                  std::bad_expected_access on error, and</li>
              </ol>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>What if the error() is a null std::exception_ptr? The
            rethrow would have undefined behaviour in that case.</div>
        </div>
      </div>
    </blockquote>
    Good point.<br>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_quote">
          <div>As nice as some of these changes might be, they would
            mean ABI breaks if we did it now. For
            std::expected&lt;T&amp;, exception_ptr&gt; we could do
            anything, because that doesn&#39;t exist now so there&#39;s no
            compatibility with existing code to worry about. But it
            would be strange if it had a completely different API from
            the non-reference std::expected&lt;T, exception_ptr&gt;
            form.</div>
          <div><br>
          </div>
          <div>One solution would be to introduce a tag type that can be
            used as the second template argument to request the
            behaviour you want, e.g. std::expected&lt;T,
            std::handle_exceptions_cleverly&gt;, but with a better name
            :-)</div>
          <div>That tag type doesn&#39;t exist today, so there would be no
            compatibility concerns here either. Anybody using the tag
            type is explicitly opting in to the alternative API. The
            error_type could still be defined as exception_ptr, rather
            than the tag type, and the monadic operations could be
            modified to catch exceptions from the callable. Something
            like a tag type was the (weakly) preferred direction for
            P3014<br>
          </div>
          <div><br>
          </div>
        </div>
      </div>
    </blockquote>
    <p> If I understand you correctly, specialising std::expected&lt;T,
      new_tag_type&gt; would be acceptable on the basis that
      new_tag_type is <u>new</u>, rather than because it is a tag type
      <i>per se</i>.</p></div></blockquote><div>Right. Nobody is using std::expected&lt;T, new_tag_type&gt; today, because std::new_tag_type doesn&#39;t exist so they *can&#39;t* be using it today. So we can give that specialization whatever new semantics we want, because it can&#39;t break anybody&#39;s code. <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><p>  The downside of a tag type is that it breaks the
      pattern of the type parameters &lt;T, E&gt; denoting the types
      &lt;value_type, error type&gt;.  But what if we specialise
      std::expected on a new <u>error</u> type
      std::non_null_exception_ptr?  I think this resolves the issue of
      ABI compatibility and avoids the problem of a null error_type.  There&#39;s
      even a reasonably good name for it :-)</p></div></blockquote><div><br></div><div>Maybe std::exception_ref, if it&#39;s a non-nullable pointer! <br></div></div></div>

