<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html class="gr__open-std_org"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<style type="text/css">
pre {margin-left:20pt; }
pre > i {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > i {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
pre > em {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
code > em {
  font-family: "OCR A Extended", "Consolas", "Lucida Console", monospace;
  font-style:italic;
}
body { color: #000000; background-color: #FFFFFF; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

p.example { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract { margin-left: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }

p.function { }
.attribute { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;
  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;
  color: #000000; background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding-left: 0.5empadding-right: 0.5em; ; }

blockquote.stdins { text-decoration: underline;
  color: #000000; background-color: #C8FFC8;
  border: 1px solid #B3EBB3; padding: 0.5em; }

table.header { border: 0px; border-spacing: 0;
  margin-left: 0px; font-style: normal; }

table { border: 1px solid black; border-spacing: 0px;
  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;
  padding-left: 0.4em; border: none; 
  padding-right: 0.4em; border: none; }
td { text-align: left; vertical-align: top;
  padding-left: 0.4em; border: none;
  padding-right: 0.4em; border: none; }
</style>

<title>bind_front should not unwrap reference_wrapper</title>
</head>

<body data-gr-c-s-loaded="true">

<table class="header"><tbody>
  <tr>
    <th>Document number:&nbsp;&nbsp;</th><th> </th><td>P1651R0</td>
  </tr>
  <tr>
    <th>Date:&nbsp;&nbsp;</th><th> </th><td>2019-06-07</td>
  </tr>
  <tr>
    <th>Audience:&nbsp;&nbsp;</th><th> </th><td>Library Evolution Working Group</td>
  </tr>
  <tr>
    <th>Reply-to:&nbsp;&nbsp;</th><th> </th><td><address>Tomasz Kamiński &lt;tomaszkam at gmail dot com&gt;</address></td>
  </tr>
</tbody></table>

<h1><a name="title"><code>bind_front</code> should not unwrap <code>reference_wrapper</code></a></h1>

<h2><a name="intro">1. Introduction</a></h2>

<p>This paper proposes a change in the behaviour of the <code>std::bind_front</code> in regards to the 
   bound arguments of the <code>std::reference_wrapper&lt;T&gt;</code> type &mdash;
   the arguments should not be unwrapped (passing <code>rw.get()</code> to underlying callable),
   and should be propagated unchanged instead (passing <code>rw</code> unmodified to underlying callable).</p>

<p>This change is the result of analysis of use case provided by the Abseil team, that I have not
   considered during the initial design. The main motivation of the change is to reduce the extent
   of damage that may be implied by code that assumes "incorrect" behavior.</p> 

<table>

  <tr>
    <th>Before: <code>bind_front</code> has unwrapping semantic</th>
    <th>After: <code>bind_front</code> has propagation semantic</th>
  </tr>

  <tr>
    <td>
      <p>Code that assumes propagation semantic may:
      <ul>
        <li>not compile (static error),</li>
        <li>create silent compies (performance impact),</li>
        <li>use dangling references (undefined behavior).</li>
      </ul></p>
    </td>

    <td>
      <p>Code that assumes unwrapping semantic may:
      <ul>
        <li>not compile (static error).</li>
      </ul></p>
    </td>
  </tr>

  <tr>
    <td>
      <p>Fixing code requires the implementation of a custom binder.</p>
    </td>

    <td>
      <p>Fixing code requires a cast to desired view type.</p>
    </td>
  </tr>


</table>

<p>Changes proposed in this paper need to be considered in the C++20 timeline, as they would constitute breaking change after the publication of standard in the current form.</p>

<!--h2><a name="toc">Table of contents</a></h2-->

<h2><a name="history">2. Revision history</a></h2>

<h3><a name="history.r0">2.1. Revision 0</a></h3>

<p>Initial revision.</p>


<h2><a name="motivation">3. Motivation and Scope</a></h2>

<p>This paper discusses the behavior of the code that uses <code>std::bind_front</code> in conjunction with <code>std::reference_wrapper</code>
   instantations. To illustrate lets consider the following code:</p>
<pre>Thingy thingy;
auto boundFunctor = std::bind_front(func, std::ref(thingy));</pre>

<p>There are two possible and conflicting behaviors of the <code>boundFunctor()</code> invocation
(for purpose of presentation we refer to bound <code>reference_wrapper</code> as <code>thingyRef</code>):
<ul>
  <li><em>unwrapping</em>: <code>func(thingyRef.get())</code>, i.e. passing <code>Thingy &amp;</code> &mdash; mimics behaviour of <code>std::bind_front</code> w.r.t. <code>reference_wrapper</code>,</li>
  <li><em>propagation</em>: <code>func(thingyRef)</code>, i.e. passing <code>std::reference_wrapper&lt;Thingy&gt;</code> &mdash; <code>std::reference_wrapper</code> is treated as any other class.</li>
</ul>
The difference between above behavior is subtle and manifest itself only in specific corner case &mdash; it's is usually not observable in the user code, 
due to the implicit conversion from <code>std::reference_wrapper&lt;Thingy&gt;</code> to <code>Thingy&amp;</code>.</p>

 
<h3><a name="motivation.double-conversion">3.1. Unwrapping use case: Double conversion</a></h3>

<p>One of the situations when the difference between unwrapping and propagation semantic is visible, is when the functor is bound
   with the reference to the object (e.g. <code>std::reference_wrapper&lt;std::string&gt;</code>, and the code accepts an view
   to it (e.g. <code>std::string_view</code>). To illustrate lets consider:</p>
<pre>
void functionAcceptingStringView(std::string_view);
void functionAcceptingSpanOfIntegers(std::span&lt;int&gt;);

std::string s; 
auto fs = std::bind_front(&amp;functionAcceptingStringView, std::ref(s));
std::vector&lt;int&gt; v;
auto fv = std::bind_front(&amp;functionAcceptingSpanOfIntegers, std::ref(v));</pre>

<p>With the unwrapping (current) semantic, both <code>fs()</code> and <code>fv()</code> compiles correctly, as <code>std::string_view</code> can be implicitly constructed from <code>std::string&amp;</code> and
   <code>std::span&lt;int&gt;</code> can be implicitly constructed from <code>std::vector&lt;int&gt;&amp;</code>.
   In case if propagation semantic was provided, both invocation would not compile, as they would require two user defined conversion to be performed:
   <ul>
    <li><code>std::reference_wrapper&lt;std::string&gt;</code> &rarr; <code>std::string&amp;</code> &rarr; <code>std::string_view</code> for <code>fs()</code>, and</li>
    <li><code>std::reference_wrapper&lt;std::vector&lt;int&gt;&gt;</code> &rarr; <code>std::vector&lt;int&gt;&amp;</code> &rarr; <code>std::span&lt;int&gt;</code> for <code>fv()</code>.</li>
  </ul>
  However, both of above compilation issues can be easily fixed by binding the desired view type instead of using <code>std::ref</code>:</p>
<pre>
auto fs = std::bind_front(&amp;functionAcceptingStringView, std::string_view(s));
auto fv = std::bind_front(&amp;functionAcceptingSpanOfIntegers, std::span(v));</pre>
  


<h3><a name="motivation.currying">3.2. Propagation use case: Function currying</a></h3>

<p>The difference between the propagation is unwrapping semantic, is that the former support rebinding of the argument.
   This can be best illustrated with the implementation of the functor <code>PartialApply</code> that implements function 
   currying in C++:</p>

<pre>template &lt;typename F&gt;
struct PartialApply {
    PartialApply(F f) : f(f) {}
    F f;

    template &lt;typename... A&gt; auto operator()(A const&amp;... a) const {
        if constexpr (std::is_invocable&lt;F const&amp;, A const&amp;...&gt;::value) {
            return f(a...);
        } else {
            return bind_front(*this, a...);
        }
    }
};</pre>

<p>The intent of the above code is that the expression <code>PartialApply(func)(a)(b)</code> is either:</p>
<ul>
   <li>calling <code>func(a, b)</code> if that is well-formed,</li>
   <li>returning callback that binds <code>func</code> with <code>a</code> and </code>b</code> and accepts consecutive arguments (<em>rebounding</em>).</p>
</ul></p>

<p>The above implementation works flawlessly in case of the propagation semantic, however, it fails in the case of unwrapping
   is used &mdash; in the case when rebinding is performed, copy of arguments that were originally passed via <code>std::ref</code> is made.</p>

<p>In the most optimistic scenario the above issue will manifest as compilation error. This happens when move only type
   is passed by reference:</p>
<pre>
std::unique_ptr&lt;Thingy&gt; thingy;
auto func = [](std::unique_ptr&lt;Thingy&gt;&amp;, int) {};

PartialApply(func)(std::ref(thingy))(10);</pre>

<p>In the case of copyable types, silently copy of the object will be created.
   This, of course, may have negative performance implication, but in the worst case can lead to dangling references:</p>
<pre>
std::string str;
auto func = [](std::string&amp; s, int) -&gt; std::string&amp; { return s; };

std::string&amp; sref = PartialApply(func)(std::ref(s))(10); // sref refers to copy of str stored in PartialApply
sref.push_back('a');                                     // use of dangling reference
</pre>

<p>Finally, the author is not aware of the way of fixing <code>PartialApply</code> than reimplementing custom
   <code>bind_front</code> alternative that has propagation semantic.</p>

<h3><a name="motivation.lwg2219">3.3. Historical design note on <a href="https://wg21.link/lwg2219">LWG 2219</a></a></h3>

<p>The prominent use case for partial function application functions (like <code>std::bind_front</code> and <code>std::bind</code>),
   is to provide a helper to compose given method on the class, with a specific object. 
   In case if invocation should be performed on existing object instance (not a copy), a <code>std::reference_wrapper</code> was used
   as follows:</p>
<pre>auto bound = std::bind_front(&Object::method, std::ref(instance));</pre>
    
<p>In the time when the <code>std::bind_front</code>  was originally proposed (also applies to <code>std::bind</code>), the above code
   to work property required unwrapping semantic (at least the for first argument).
   This was changed with the resolution of <a href="https://wg21.link/lwg2219">LWG 2219: <code><em>INVOKE</em></code>-ing a pointer to member with a <code>reference_wrapper</code> as the object expression</a>,
   that have introduced dedicated handling for <code>std::reference_wrapper</code> in <code><em>INVOKE</em></code>,
   and unwrapping of <code>std::reference_wrapper</code> is no longer required to achieve this functionality.</p>


<h2><a name="design">4. Design Decisions</a></h2>

<h3><a name="design.preffering-compliation-error">4.1. Preference for compilation errors</a></h3>

<p>As indicated in the motivation section, the difference between unwrapping and propagation semantic manifest
   itself in a very specific scenario. As a consequence, the user, unaware of this specific behavior,
   may accidentally create an erroneous code that depends on semantic other that one supplied by the standard.
   In that case, it would be desired that error is detected as early as possible, preferably at compile time.<p> 
  
<p>In light of the above, this paper proposes to switch to propagation semantic, as code that assumes unwrapping
   becomes ill-formed. With the current behavior (unwrapping), the code that assumes propagation may lead
   to runtime bugs.</p>


<h3><a name="design.no-side-effects">4.2. Preserving other behavior</a></h3>

<p>The change proposed in this paper has no impact on user-visible behaviour of <code>std::bind_front</code> ,
   despite the fact that functors returned by this functor will now store <code>std::reference_wrapper&lt;T&gt;</code> instead
   of <code>T&amp;</code>, as:
<ul>
  <li>functors produced by <code>std::bind_front</code> are not assignable, so the difference in assignment semantic is not visible to the user,</li>
  <li><code>reference_wrapper</code>, like references, is required to be trivially copyable,</li>
  <li><code>bind_front</code> is not currently usable in <code>constexpr</code> context.</li>
</ul></p>

<p>In addition the <a href="https://wg21.link/p1065">P1065: <code>constexpr <em>INVOKE</em></code></a> applies <code>constexpr</code>
   to <code>std::reference_wrapper</code>.</p>

<h2><a name="wording">5. Proposed Wording</a></h2>

<p>The proposed wording changes refer to <a href="http://wg21.link/n4810"></a> N4810 (C++ Working Draft, 2019-03-15).</p>

<p>Apply following changes to section [func.bind_front] Function template <code>bind_front</code>:</p>
<blockquote class="std">
  <pre>  template &lt;class F, class... Args&gt;
     <em>unspecified</em> bind_front(F&amp;&amp; f, Args&amp;&amp;... args);
  </pre>

  <dl class="attribute">

    <dd>In the text that follows:
    <ul>
      <li><code>g</code> is a value of the result of a <code>bind_front</code> invocation,</li>

      <li><code>FD</code> is the type <code>decay_t&lt;F&gt;</code>,</li>
      <li><code>fd</code> is a target object of <code>g</code> ([func.def])
           of type <code>FD</code>
           initialized with <em>initializer</em> <code>(std::forward&lt;F&gt;(f))</code>,</li>
      <li><code>BoundArgs</code> is a pack that denotes <code><del>std::unwrap_­ref_­</del>decay_­t&lt;Args&gt;...</code>,</li>
      <li><code>bound_args</code> is a pack of bound argument entities of <code>g</code> ([func.def])
           of types <code>BoundArgs...</code> 
           initialized with <em>initializers</em> <code>(std::forward&lt;Args&gt;(args))...</code> respectively, and</li>
      <li><code>call_args</code> is an argument pack used in a function call expression ([expr.call]) of <code>g</code>,</li>
    </ul>
    <p></p></dd>

  </dl>
</blockquote>

<p>Update the value of the <code>__cpp_lib_bind_front</code> in table "Standard library feature-test macros" of [support.limits.general] to reflect the date of approval of this proposal.</p>

<h2><a name="implementability">6. Implementability</a></h2>

<p>This paper can be implemented by simply replacing <code>unwrap_ref_decay_t</code> with <code>decay_t</code> in example implementation from "Implementability"
   section of the <a href="https://wg21.link/p0356r5">P0365R5: Simplified partial function application</a> paper.</p>

<h2><a name="acknowledgements">7. Acknowledgements</a></h2>

<p>Titus Winters and Abseil team for providing the feedback on the <code>bind_front</code> and code example that motivated creation of this paper.</code>

<p>Samuel Benzaquen for providing feedback and corrections for this paper.</p>

<p>Special thanks and recognition goes to Sabre (<a href="http://www.sabre.com/">http://www.sabre.com</a>) for supporting the production of this proposal
   and author's participation in standardization committee.</p>

<h2><a name="literature">8. References</a></h2>

<ol>
  <li>Jonathan Wakely,
      Issue 2219. <code><em>INVOKE</em></code>-ing a pointer to member with a <code>reference_wrapper</code> as the object expression,
      (LWG2219, <a href="https://wg21.link/lwg2219">https://wg21.link/lwg2219</a>)</li>

  <li>Barry Revzin,
      <code>constexpr <em>INVOKE</em></code>,
      (P1065, <a href="https://wg21.link/p1065">https://wg21.link/p1065</a>)</li>

  <li>Richard Smith,
      "Working Draft, Standard for Programming Language C++"
      (N4810, <a href="https://wg21.link/n4810">https://wg21.link/n4810</a>)</li>

  <li>Tomasz Kamiński,
      Simplified partial function application,
      (P0356R5, <a href="https://wg21.link/p0356r5">https://wg21.link/p0356r5</a>)</li>

</ol>


</body></html>
