<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><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>Parameter group placeholders for bind</title>
</head>

<body>

<table class="header"><tbody>
  <tr>
    <th>Document number:&nbsp;&nbsp;<th> <td>N4171</td>
  </tr>
  <tr>
    <th>Date:&nbsp;&nbsp;<th> <td>2014-10-05</td>
  </tr>
  <tr>
    <th>Project:&nbsp;&nbsp;<th> <td>Programming Language C++, Library Evolution Working Group</td>
  </tr>
  <tr>
    <th>Reply-to:&nbsp;&nbsp;<th> <td><address>Tomasz Kamiński &lt;tomaszkam at gmail dot com&gt;</address></td>
  </tr>
</tbody></table>

<h1><a name="title">Parameter group placeholders for bind</a></h1>

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

<p>The aim of this proposal is to introduce a new class of placeholder that could be used with <code>std::bind</code>:
a group placeholder that represents a set of (zero or more) call arguments.</p>

<p>This paper addresses <a href="https://issues.isocpp.org/show_bug.cgi?id=40">LEWG Bug 40: variadic bind</a>.</p>

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

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

<p>Before going thought this chapter the author recommends the reader to familiarize with 
<a href="#appendix.bind_vs_lambda">Appendix: Why we need <code>bind</code> when we have a generic lambda?</a>.</p>

<p>In the scope of this proposal we introduce a new type of parameter placeholder: group placeholders
that are to be replaced by zero or more arguments in the invocation of the stored functor.
The meaning of a single placeholder is independent from the context, so if the given placeholder is used
twice, appropriate set of values will be passed twice, reproducing existing behaviour.</p>

<p>The following group placeholders are proposed in this paper:</p>
<table>
  <tr><th>placeholder</th>                      <th>range of arguments</th></tr>
  <tr><td><code>_all</code></td>                <td>[1st, last]</td></tr>
  <tr><td><code>_from&lt;N&gt;</code></td>      <td>[Nth, last]</td></tr>
  <tr><td><code>_to&lt;N&gt;</code></td>        <td>[1st, Nth)</td></tr>
  <tr><td><code>_between&lt;N, K&gt;</code></td><td>[Nth, Kth)</td></tr>
</table>
<p>To complement set of group placeholders, the variable template representation of a single-argument placeholder named
<code>_at&lt;N&gt;</code> is also proposed.</p>

<h3><a name="motivation.mem_fn-reproduction">Binding object with member function</a></h3>

<p>The most common use case for placeholder <code>_all</code> is to bind an object to a member function,
effectively emulating the result of expressions <code>obj.*ptr</code>.</p>

<p>For example, given the following definitions:</p>
<pre>struct Strategy { double process(std:string, std::string, double, double); };
std::unique_ptr&lt;Strategy&gt; createStrategy();</pre>

<p>We want to create a functor that will invoke method <code>process</code> on a given strategy. Compare the two solutions, one using lambda, the other using <code>bind</code>: </p>
<pre>[s = createStrategy()] (auto&amp;&amp;... args) -&gt; decltype(auto) { return s-&gt;process(std::forward&lt;decltype(args)&gt;(args)...); }</pre>
<pre>std::bind(&amp;Strategy::process, createStrategy(), _1, _2, _3, _4)</pre>

<p>The lambda approach allow us to write a functor that will be immune to the changes in the number of method arguments, 
but it requires an explicit specification of the return type and the use of perfect forwarding to accomplish such a simple task. 
The solution that uses <code>bind</code> is pretty straightforward, but it requires a modification every time the number of parameters
of the method changes. 
The extension proposed in this paper allows us to avoid this problem by writing:</p>
<pre>std::bind(&amp;Strategy::process, createStrategy(), _all)</pre>

<p>The same problem is also addressed by paper <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3702.htm">N3702</a>,
 by the introduction of a new version of function <code>mem_fn</code>:</p>
 
<pre>std::mem_fn(&amp;Strategy::process, createStrategy())</pre>

<p>Although the solution presented in N3702 provides nice and concise syntax, it address only this specific use case, 
and can be easily emulated with <code>std::bind</code> and group placeholder:</p>
<pre>template&lt;typename Class, typename Member, typename Object&gt;
auto mem_fn(Member Class::* mem_ptr, Object&amp;&amp; obj)
{ return std::bind(mem_ptr, std::forward&lt;Object&gt;(obj), _all); }
</pre>

<h3><a name="motivation.argument-list-manipulation">Argument list manipulation</a></h3>

<p>With the proposed set of the placeholders a programmer is able to perform various types of manipulation with the argument list, 
including, but not limited to:</p>
<ul>
  <li>insert new argument at Nth position: <code>bind(f{}, _to&lt;N&gt;, val, _from&lt;N&gt;)</code></li>
  <li>replace Nth argument with given value: <code>bind(f{}, _to&lt;N&gt;, val, _from&lt;N+1&gt;)</code></li>
  <li>change order of first and second argument: <code>bind(f{}, _2, _1, _from&lt;3&gt;)</code></li>
  <li>swap positions of Nth and Kth argument: <code>bind(f{}, _to&lt;N&gt;, _at&lt;K&gt;, _between&lt;N+1, K&gt;, _at&lt;N&gt;, _from&lt;K+1&gt;)</code></li>
  <li>forward only first N arguments: <code>bind(f{}, _to&lt;N&gt;)</code></li>
  <li>drop first N arguments: <code>bind(f{}, _from&lt;N+1&gt;)</code></li>
</ul>

<h3><a name="motivation.custom-placeholder">Defining custom placeholders</a></h3>

<p>The existing design of <code>std::bind</code> allows the programmer to specify his own placeholder types via the specialization of trait <code>is_placeholder</code>. It is used
 both to check if a given type <code>P</code> represents placeholder (<code>is_placeholder&lt;P&gt;::value &gt; 0</code>) and to define the index
of the call argument that will be passed as a replacement of the placeholder (<code>is_placeholder&lt;P&gt;::value</code>).</p>

<p>The extension proposed in this paper, preserves this functionality, and also adds the ability to create user-defined group placeholders.
To achieve this goal the previous responsibility of the <code>is_placeholder</code> is divided into two separate type functions:</p>
<ul>
  <li><code>is_placeholder</code> that is used to determine if given type <code>P</code> represents a placeholder.
  To mark type as placeholder, the specialization <code>is_placeholder&lt;P&gt;</code> should be derived from <code>integral_constant&lt;int, K&gt;</code>,
  where <code>K &gt; 0</code>.</li>

  <li><code>parameter_indices</code> that is used to determine indices of call arguments that should be passed as replacement of the placeholder.
  This type trait accepts the number of call arguments passed to functor as a second parameter.
  To signal that arguments with indices <code>i1, i2, ..., iK</code> should be used instead of placeholder, the specialization of the
  <code>parameter_indices&lt;T, N&gt;</code> should be derived from <code>integer_sequence&lt;int, i1, i2, ..., iK&gt;</code>.</li>
</ul>
<p>To preserve backward compatibility with the existing single argument placeholders, the default implementation of <code>parameter_indices&lt;P, N&gt;</code>
is derived from <code>integer_sequence&lt;int, is_placeholder&lt;P&gt;::value&gt;</code> for every placeholder type <code>P</code>.</p>

<p>An example implementation of <code>_args</code> placeholder that accepts indices of arguments that should be forwarded is provided bellow:</p>
<pre>template&lt;int... Is&gt;
struct args_placeholder {};

template&lt;int... Is&gt;
constexpr args_placeholder _args{};

namespace std
{
  template&lt;int... Is&gt;
  struct is_placeholder&lt;args_placeholder&lt;Is...&gt;&gt;
    : integral_constant&lt;int, 1&gt; {};

  template&lt;int... Is, int N&gt;
  struct parameter_indices&lt;args_placeholder&lt;Is...&gt;, N&gt;
   : integer_sequence&lt;int, Is...&gt; {};
}</pre>

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

<h3><a name="design.variable-templates">Use of variables templates to define placeholders</a></h3>

<p>The variable templates are used to define placeholders instead of set of extern variables. This approach allows
the programmer to compute positions of passed parameters at compile time, which is cumbersome in case of existing placeholders.
In addition the author finds single definition of <code>_from</code>, instead list of <code>_1onwards, _2onwards, ..., _Nonwards</code>,
being more elegant.</p>

<h3><a name="design.names">Naming of placeholders</a></h3>

<p>Parameter group placeholder proposed in this paper has names that begins with underscore (<code>_all</code>, <code>_from</code>)
   instead of the most obvious <code>all</code>, <code>from</code>. These names was chosen to reduce risk name collision in code,
   that uses <code>bind</code> in combination with using directive for <code>std::placeholders</code> namespace. Example:</p>
<pre>
  std::vector&lt;std::string&gt; erase_empty(std::vector&lt;std::string&gt; v)
  {
    using namespace std;
    using namespace std::placeholders;

    auto from = remove_if(begin(v), end(v), bind(&amp;string::empty, _1));
    v.erase(from, end(v));
    return v;
  }
</pre>

<p>Furthermore the author perceive this names as more consistent with the existing numbered placeholders (<code>_1</code>, <code>_2</code>, ...).</p>

<h3><a name="design.from">Number of parameters required by <code>_from&lt;N&gt;</code></a></h3>

<p>The addition of the <code>_from&lt;N&gt;</code> placeholder opens the question about its behaviour when the number of parameters 
   passed to the forwarding call wrapper produced as a result of <code>bind(&amp;foo, _from&lt;N&gt;)</code> is equal to <code>N-1</code>. There are two possible approaches:</p>
<ol>
  <li>forward no arguments in place of <code>_from&lt;N&gt;</code> to target callable object,</li>
  <li>make such invocation ill-formed and require at least <code>N</code> arguments if the <code>_from&lt;N&gt;</code> is used.</li>
</ol>
<p>The first behaviour was chosen by this proposal, because it is more general and allows to easily simulate the second one by passing 
   <code>_N, _from&lt;N+1&gt;</code> instead of <code>_from&lt;N&gt;</code> as argument.</p>
   
<h3><a name="design.int-index">Non-type template argument of type <code>int</code></a></h3>

<p>The non-type template argument of <code>_at</code>, <code>_from</code>, <code>_to</code>, <code>_between</code> and <code>parameter_indices</code>
   has an <code>int</code> type, although they values are required to be non-negative. 
   This decision was made to keep them consistent with existing <code>is_placeholder</code> trait, that uses <code>int</code> to represent index of forwarded parameter.</p>

<h2><a name="standard">Impact On The Standard</a></h2>

<p>This proposal has no dependencies beyond a C++14 compiler and Standard Library implementation. 
   (It depends on perfect forwarding, varidatic templates, variable templates, <code>decltype</code> and trailing return types.)</p>

<p>Nothing depends on this proposal.</p>

<h2><a name="wording">Proposed wording</a></h2>

<p>Change the section 20.10 [function.objects]/2.</p>

<blockquote class="std"> 
<pre>
// 20.10.9, <em>bind</em>:
template&lt;class T&gt; struct is_bind_expression;
template&lt;class T&gt; struct is_placeholder;
<ins>template&lt;class T, int N&gt; struct parameter_indices;</ins>

template&lt;class F, class... BoundArgs&gt;
  <em>unspecified</em> bind(F&amp;&amp;, BoundArgs&amp;&amp;...);
template&lt;class R, class F, class... BoundArgs&gt;
  <em>unspecified</em> bind(F&amp;&amp;, BoundArgs&amp;&amp;...);

namespace placeholders {
  // <em>M is the implementation-defined number of placeholders</em>
  extern <em>unspecified</em> _1;
  extern <em>unspecified</em> _2;
  .
  .
  .
  extern <em>unspecified</em> _M;

<ins>  template&lt;int N&gt;
  <em>unspecified</em> _at;

  template&lt;int N&gt;
  <em>unspecified</em> _from;

  template&lt;int N&gt;
  <em>unspecified</em> _to;

  template&lt;int B, int E&gt;
  <em>unspecified</em> _between;

  extern <em>unspecified</em> _all;</ins>
}
</pre>
</blockquote>

<p>Change the paragraph 20.10.9.1.2 Class template <code>is_placeholder</code> [func.bind.isplace].</p>

<blockquote class="std">
  <dl class="attribute">

    <dd><p><code>is_placeholder</code> can be used to detect the standard placeholders <ins><code>_all</code>, <code>_between&lt;B, E&gt;</code>, <code>_to&lt;N&gt;</code>, 
           <code>_from&lt;N&gt;</code>, <code>_at&lt;N&gt;</code>,</ins> <code>_1</code>, <code>_2</code>, and so on.
           <code>bind</code> uses <code>is_placeholder</code> to detect placeholders.</p></dd>

    <dd><p>Instantiations of the <code>is_placeholder</code> template shall meet the UnaryTypeTrait requirements (20.11.1).
           The implementation shall provide a definition that has the BaseCharacteristic of<del> <code>integral_constant&lt;int, J&gt;</code>
           if <code>T</code> is the type of <code>std::placeholders::_J</code>, otherwise it shall have a BaseCharacteristic of
           <code>integral_constant&lt;int, 0&gt;</code>.</del><ins>:</ins>
        </p><ins><ul>
           <li><code>integral_constant&lt;int, 1&gt;</code> if <code>T</code> is the type of <code>std::placeholders::_all</code>,</li>
           <li><code>integral_constant&lt;int, 1&gt;</code> if <code>T</code> is the type of <code>std::placeholders::_from&lt;N&gt;</code> and <code>N &gt; 0</code>,</li>
           <li><code>integral_constant&lt;int, 1&gt;</code> if <code>T</code> is the type of <code>std::placeholders::_to&lt;N&gt;</code> and <code>N &gt; 0</code>,</li>
           <li><code>integral_constant&lt;int, 1&gt;</code> if <code>T</code> is the type of <code>std::placeholders::_between&lt;B, E&gt;</code> and <code>B &gt; 0</code> and <code>E &gt;= B</code>,</li>
           <li><code>integral_constant&lt;int, J&gt;</code> if <code>T</code> is the type of <code>std::placeholders::_at&lt;J&gt;</code> or <code>std::placeholders::_J</code>,</li>
           <li><code>integral_constant&lt;int, 0&gt;</code> otherwise.</li>
        </ul></ins>
        <p>A program may specialize this template for a user-defined type <code>T</code> to
           have a BaseCharacteristic of <code>integral_constant&lt;int, N&gt;</code> with <code>N &gt; 0</code> to indicate that <code>T</code>
           should be treated as a placeholder type.</p></dd>
  </dl>
</blockquote>

<p>After paragraph 20.10.9.1.2 Class template <code>is_placeholder</code>, insert a new paragraph. (Paragraph 20.10.9.1.3 Function template <code>bind</code> [func.bind.bind] becomes 20.10.9.1.?)</p>
  
<blockquote class="stdins"> 
<h4>20.10.9.1.3 Class template <code>parameter_indices</code> <span style="float:right">[func.bind.paramidx]</span></h4>

<pre>
namespace std {
  template&lt;class T, int N&gt; struct parameter_indices; // see below
}</pre>

  <dl class="attribute">
    <dd><p><code>bind</code> uses <code>parameter_indices</code> to determine indices of parameters of the forwarding call wrapper
           to be forwarded to stored callable object as replacement for placeholder.</p></dd>

    <dd><p>The implementation shall provide a definition of <code>parameter_indices&lt;T, N&gt;</code> that is publicly and unambiguously derived from:
    </p><ul>
      <li><code>integer_sequence&lt;int&gt;</code> 
          if <code>T</code> is the type of <code>std::placeholders::_all</code> and <code>N == 0</code>,</li>
      <li><code>integer_sequence&lt;int, 1, 2, ..., N&gt;</code> 
          if <code>T</code> is the type of <code>std::placeholders::_all</code> and <code>N &gt; 0</code>,</li>
      <li><code>integer_sequence&lt;int&gt;</code>
          if <code>T</code> is the type of <code>std::placeholders::_between&lt;B,B&gt;</code> and <code>N &gt;= B-1</code>,</li>
      <li><code>integer_sequence&lt;int, B, B+1, ..., E-1&gt;</code>
           if <code>T</code> is the type of <code>std::placeholders::_between&lt;B,E&gt;</code> and <code>B &lt; E</code> and <code>N &gt;= E-1</code>,</li>
      <li><code>integer_sequence&lt;int&gt;</code>
          if <code>T</code> is the type of <code>std::placeholders::_to&lt;1&gt;</code> and <code>N &gt;= 0</code>,</li>
      <li><code>integer_sequence&lt;int, 1, 2, ..., K-1&gt;</code>
          if <code>T</code> is the type of <code>std::placeholders::_to&lt;K&gt;</code> and <code>N &gt;= K-1</code>,</li>
      <li><code>integer_sequence&lt;int&gt;</code>
          if <code>T</code> is the type of <code>std::placeholders::_form&lt;K&gt;</code> and <code>N == K-1</code>,</li>
      <li><code>integer_sequence&lt;int, K, K+1, ..., N&gt;</code>
          if <code>T</code> is the type of <code>std::placeholders::_form&lt;K&gt;</code> and <code>N &gt;= K</code>,</li>
      <li><code>integer_sequence&lt;int, j&gt;</code>
          if <code>T</code> is not one of the types described in the previous items
          and the value <code>j</code> defined as <code>is_placeholder&lt;T&gt;::value</code> is positive and <code>N &gt;= j</code>,</li>
    </ul><p></p></dd>

    <dd><p>A program may specialize or partially specialize <code>parameter_indices</code> template for a user-defined placeholder type to be publicly and 
           unambiguously derived from <code>integer_sequence&lt;int, i1, i2, ..., iN&gt;</code> with values <code>i1, i2, ..., iN</code> greater than zero,
           to indicate indices of parameters of the forwarding call wrapper to be forwarded to stored callable object as replacement for placeholder.</p></dd>

    <dd><p>A program is ill-formed if it necessitates the instantiation of <code>parameter_indices&lt;T, N&gt;</code> that does not satisfy criteria of any of the bullets in paragraph 1
           and does not match a specialization or a partial specialization of template <code>parameter_indices</code> defined in the program.</p></dd>

  </dl>

</blockquote>

<p>Change the paragraph 20.10.9.1.3 Function template <code>bind</code> [func.bind.bind].</p>

<blockquote class="std">
<pre>
template&lt;class F, class... BoundArgs&gt;
  <em>unspecified</em> bind(F&amp;&amp; f, BoundArgs&amp;&amp;... bound_args);
</pre>

  <dl class="attribute">

    <dt>Requires:</dt>
    <dd><p><code>is_constructible&lt;FD, F&gt;::value</code> shall be true.
           For each <code>Ti</code> in <code>BoundArgs</code>, <code>is_constructible&lt;TiD, Ti&gt;::value</code> shall be true.
           <del><code>INVOKE (fd, w1, w2, ..., wN)</code> (20.10.2) shall be a valid expression for some values <code>w1, w2, ..., wN</code>, where <code>N == sizeof...(bound_args)</code>.</del>
           <ins><code>fd</code> shall be a callable object ([func.def] 20.10.1).</ins></p></dd>

    <dt>Returns:</dt>
    <dd><p>A forwarding call wrapper <code>g</code> with a weak result type (20.10.2).
           The effect of <code>g(u1, u2, ..., uM)</code> shall be 
           <del><code><em>INVOKE</em> (fd, std::forward&lt;V1&gt;(v1), std::forward&lt;V2&gt;(v2), ..., std::forward&lt;VN&gt;(vN), 
                                           result_of&lt;FD <em>cv</em> &amp; (V1, V2, ..., VN)&gt;::type)</code></del>
           <ins><code><em>INVOKE</em> (fd, std::forward&lt;P1&gt;(p1)..., std::forward&lt;P2&gt;(p2)..., ..., std::forward&lt;PN&gt;(pN)...)</code></ins>,
           where <code><em>cv</em></code> represents the cv-qualifiers of <code>g</code> and the values and types of <del>the</del>
           <ins>elements of each of</ins> bound arguments <del><code>v1, v2, ..., vN</code></del> <ins>packs <code>p1, p2, ..., pN</code></ins>
           are determined as specified below.
           The copy constructor and move constructor of the forwarding call wrapper shall throw an exception if and only if the corresponding
           constructor of <code>FD</code> or of any of the types <code>TiD</code> throws an exception.
         </p></dd>

    <dt>Throws:</dt>
    <dd><p>Nothing unless the construction of <code>fd</code> or of one of the values <code>tid</code> throws an exception.</p></dd>

    <dt>Remarks:</dt>
    <dd><p>The return type shall satisfy the requirements of <code>MoveConstructible</code>.
           If all of <code>FD</code> and <code>TiD</code> satisfy the requirements of <code>CopyConstructible</code>,
           then the return type shall satisfy the requirements of <code>CopyConstructible</code>.
           [ <em>Note:</em> This implies that all of FD and TiD are MoveConstructible. <em>— end note</em> ]
     </p></dd>

  </dl>

<pre>
template&lt;class R, class F, class... BoundArgs&gt;
  <em>unspecified</em> bind(F&amp;&amp; f, BoundArgs&amp;&amp;... bound_args);
</pre>

  <dl class="attribute">

    <dt>Requires:</dt>
    <dd><p><code>is_constructible&lt;FD, F&gt;::value</code> shall be true.
           For each <code>Ti</code> in <code>BoundArgs</code>, <code>is_constructible&lt;TiD, Ti&gt;::value</code> shall be true.
           <del><code>INVOKE (fd, w1, w2, ..., wN)</code> (20.10.2) shall be a valid expression for some values <code>w1, w2, ..., wN</code>, where <code>N == sizeof...(bound_args)</code>.</del>
           <ins><code>fd</code> shall be a callable object ([func.def] 20.10.1).</ins></p></dd>

    <dt>Returns:</dt>
    <dd><p>A forwarding call wrapper <code>g</code> with a weak result type (20.10.2).
           The effect of <code>g(u1, u2, ..., uM)</code> shall be 
           <del><code><em>INVOKE</em> (fd, std::forward&lt;V1&gt;(v1), std::forward&lt;V2&gt;(v2), ..., std::forward&lt;VN&gt;(vN), R)</code></del>
           <ins><code><em>INVOKE</em> (fd, std::forward&lt;P1&gt;(p1)..., std::forward&lt;P2&gt;(p2)..., ..., std::forward&lt;PN&gt;(pN)..., R)</code></ins>
           , where <code><em>cv</em></code> represents the cv-qualifiers of <code>g</code> and the values and types of <del>the</del>
           <ins>elements of each of</ins> bound arguments <del><code>v1, v2, ..., vN</code></del> <ins>packs <code>p1, p2, ..., pN</code></ins>
           are determined as specified below.
           The copy constructor and move constructor of the forwarding call wrapper shall throw an exception if and only if the corresponding
           constructor of <code>FD</code> or of any of the types <code>TiD</code> throws an exception.
         </p></dd>

    <dt>Throws:</dt>
    <dd><p>Nothing unless the construction of <code>fd</code> or of one of the values <code>tid</code> throws an exception.</p></dd>

    <dt>Remarks:</dt>
    <dd><p>The return type shall satisfy the requirements of <code>MoveConstructible</code>.
           If all of <code>FD</code> and <code>TiD</code> satisfy the requirements of <code>CopyConstructible</code>,
           then the return type shall satisfy the requirements of <code>CopyConstructible</code>.
           [ <em>Note:</em> This implies that all of FD and TiD are MoveConstructible. <em>— end note</em> ]
     </p></dd>

   <dd><p>The values of <del>the</del><ins>elements of each</ins> <em>bound arguments</em> 
          <del><code>v1, v2, ..., vN</code></del> <ins><em>pack</em> <code>pi</code></ins>
          and their corresponding types <del><code>V1, V2, ..., VN</code></del> depend on the 
          type<del>s</del> <code>TiD</code> derived from the call to <code>bind</code><ins>, 
          number of parameter passed to invocation forwarding call wrapper <code>M = sizeof...(UnBoundArgs)</code></ins>
          and the cv-qualifiers <code>cv</code> of the call wrapper <code>g</code> as follows:
    </p>
    <ul>
      <li>if <code>TiD</code> is <code>reference_wrapper&lt;T&gt;</code>,
          <del>the argument is</del><ins>the pack contains single element with value</ins> <code>tid.get()</code>
          <del>and its type <code>Vi</code> is</del><ins>of type</ins> <code>T&amp;</code>;</li>
      <li>if the value of <code>is_bind_expression&lt;TiD&gt;::value</code> is true,
          <del>the argument is</del><ins>the pack contains single element with value</ins> <code>tid(std::forward&lt;Uj&gt;(uj)...)</code> 
          <del>and its type <code>Vi</code> is</del><ins>of type</ins> <code>result_of&lt;TiD <em>cv</em> &amp; (Uj&amp;&amp;...)&gt;::type&amp&amp</code>;</li>
      <li>if the value <code>j</code> of <code>is_placeholder&lt;TiD&gt;::value</code> is <del>not zero</del><ins>positive</ins>
          <ins>and <code>parameter_indices&lt;TiD, M&gt;</code> is derived from <code>integer_sequence&lt;int, j1, j2, ..., jK&gt;</code></ins>,
          <del>the argument is <code>std::forward&lt;Uj&gt;(uj)</code>  and its type <code>Vi</code> is <code>Uj&amp;&amp;</code></del>
          <ins>the pack contains <code>K</code> elements with values <code>std::forward&lt;Uj1&gt;(uj1), std::forward&lt;Uj2&gt;(uj2), ..., std::forward&lt;UjK&gt;(ujK)</code>
          of types <code>Uj1&amp;&amp;, Uj2&amp;&amp;, ..., UjK&amp;&amp;</code> respectively</ins>;</li>
      <li>otherwise, <del>the value is</del><ins>the pack contains single element with value</ins> <code>tid</code> 
          <del>and its type <code>Vi</code> is</del><ins>of type</ins> <code>TiD <em>cv</em> &amp;</code>.</li>
    </ul><p></p></dd>

  </dl>
</blockquote>

<p>Change the paragraph 20.10.9.1.4 Placeholders [func.bind.place].</p>

<blockquote class="std"> 
<pre>
namespace placeholders {
  // <em>M is the implementation-defined number of placeholders</em>
  extern <em>unspecified</em> _1;
  extern <em>unspecified</em> _2;
  .
  .
  .
  extern <em>unspecified</em> _M;

<ins>  template&lt;int N&gt;
  <em>unspecified</em> _at;

  template&lt;int N&gt;
  <em>unspecified</em> _from;

  template&lt;int N&gt;
  <em>unspecified</em> _to;

  template&lt;int B, int E&gt;
  <em>unspecified</em> _between;

  extern <em>unspecified</em> _all;</ins>
}
</pre>

  <dl class="attribute">

    <dd><p>All placeholder types shall be <code>DefaultConstructible</code> and <code>CopyConstructible</code>,
           and their default constructors and copy/move constructors shall not throw exceptions.
           It is implementation-defined whether placeholder types are <code>CopyAssignable</code>.
           <code>CopyAssignable</code> placeholders’ copy assignment operators shall not throw exceptions.</p></dd>

           <dd><p><ins>A program that necessitates the instantiation of <code>_at&lt;N&gt;</code>, <code>_from&lt;N&gt;</code> or <code>_to&lt;N&gt;</code> with <code>N &lt;= 0</code> is ill-formed.</ins></p></dd>
           
           <dd><p><ins>A program that necessitates the instantiation of <code>_between&lt;B, E&gt;</code> with <code>B &lt;= 0</code> or <code>E &lt;= 0</code> or <code>B &gt; E</code> is ill-formed.</ins></p></dd>

  </dl>

</blockquote>


<h2><a name='implementability'>Implementability</a></h2>

<p>Proposed change can be implemented as pure library extension in C++14. Implementation of <code>bind</code> function that conforms proposed wording can be found <a href="https://github.com/tomaszkam/proposals/tree/master/bind">https://github.com/tomaszkam/proposals/tree/master/bind</a>.</p>

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

<p>Jonathan Wakely originally proposed idea of multi parameter placeholders in discussion group <a href="https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/CxpGVY1APcs/_RYAajMGhcUJ">ISO C++ Standard - Future Proposals</a>.</p>
<p>Andrzej Krzemieński and Ville Voutilainen offered many useful suggestions and corrections to the proposal.</p>


<h2><a name="appendix.bind_vs_lambda">Appendix: Why we need <code>bind</code> when we have a generic lambda?</a></h2>

<p>After the introduction of generic lambda and extensions to lambda capture, a portion of the C++ community expresses an opinion
that <code>std::bind</code> is no longer necessary and should no longer be recommend and even become deprecated.
The author disagrees with this opinion, and in support of his position, a number of use cases is discussed here
that illustrate the superiority of <code>std::bind</code> over lambdas.</p>

<p>The author wants to emphasise that the aim of this section is to demonstrate situations where <code>std::bind</code> leads
to more readable and less error prone code than lambdas. It is <em>not</em> to prove that <code>bind</code>
should be used instead of lambda in every context.</p>

<h3><a name="appendix.bind_vs_lambda.return">Specifying return type</a></h3>

<p>The default return type deduction for a lambda will preform return by value, which is an optimal approach
when a built-in type is returned; for example when we use lambda to write a predicate (function returning <code>bool</code>)
for STL algorithms; but it introduces performance overhead if returning by reference would be preferred.</p>

<p>Let's assume that we want to transform a vector of <code>Employee</code> (<code>ve</code>) in to a vector
of full names.</p>
<pre>std::transform(std::begin(ve), std::end(ve), std::back_inserter(vfn),
               [](const Employee&amp; e) { return e.full_name(); });</pre>
               
<p>If the <code>full_name</code> function returns a <code>const std::string&amp;</code>, then above code will lead to
copy of the string being created for every iteration to return value form the lambda and then element of vector will get
initialized from this temporary. In this case cheap move construction will be used, but for legacy classes
copy constructor may be used twice. To avoid the above problem we may specify the return type for a lambda.</p>
<pre>std::transform(std::begin(ve), std::end(ve), std::back_inserter(vfn),
               [](const Employee&amp; e) -> const auto&amp; { return e.full_name(); });</pre>
               
<p>This approach will fix above problems, but if the function <code>full_name</code> is changed to
return by value, then the code will cause a dangling reference problem. To avoid such problems we may use
the <code>decltype(auto)</code> deduction:

<pre>std::transform(std::begin(ve), std::end(ve), std::back_inserter(vfn),
               [](const Employee&amp; e) -> decltype(auto) { return e.full_name(); });</pre>

<p>If we attempt to repeat the same exercise using standard function wrappers, none of the above tough reasoning is necessary,
and additionally we will benefit from a single syntax for handling method pointers and member pointers.<p>

<pre>std::transform(std::begin(ve), std::end(ve), std::back_inserter(vfn),
               std::mem_fn(&amp;Employee::full_name));</pre>

               
<h3><a name="appendix.bind_vs_lambda.arguments">Passing arguments</a></h3>

<p>One of the decisions that programmer must make when writing a lambda (and any other functions) is to decide how to 
pass arguments to it. If we write a comparator or a predicate that only checks the state of the object, then we can use
<code>const auto&amp;</code>. The choice becomes less obvious if we want to write a wrapper around a function that 
accepts arguments by value, for example:</p>
<pre>std::string concat_several_times(std::string val, std::size_t n);</pre>

<p>We want to create a function that will concatenate given string 3 times. Lets begin with:</p>
<pre>[](std::string val) { return concat_serveral_times(std::move(val), 3); }</pre>

<p>The above solution will create a temporary <code>std::string</code> every time the lambda is invoked, even if the C-style string
is passed to the function. Also, we will always have a second temporary being created from the rvalue reference.
In case of the <code>std::string</code> this will end up with cheap move-construction, but it may as well introduce additional copies
for legacy classes that define only custom copy-construction. To avoid these problems we will use perfect forwarding to
pass a parameter.</p>

<pre>[](auto&amp;&amp; val) { return concat_serveral_times(std::forward&lt;<em>some_type</em>&gt;(val), 3); }</pre>

<p>What type should we use as <code><em>some_type</em></code>? If we use <code>decltype(val)</code> then above
code would be equivalent to:</p>
<pre>template&lt;typename T&gt; void foo(T&amp;&amp; t) { bar(std::forward&lt;T&amp;&amp;&gt;(t)); }</pre>
<p>Instead of the usual:</p>
<pre>template&lt;typename T&gt; void foo(T&amp;&amp; t) { bar(std::forward&lt;T&gt;(t)); }</pre>

<p>Are you ok with this additional rvalue reference? We could get rid of it by using <code>std::remove_rvalue_reference_t&lt;decltype(val)&gt;</code>,
but according definition of <code>std::forward</code>, the behaviour is same in both cases. So finally, we can safely stick to:</p>
<pre>[](auto&amp;&amp; val) { return concat_serveral_times(std::forward&lt;decltype(val)&gt;(val), 3); }</pre>

<p>The <code>std::bind</code> creates functors that perfectly forwards all non-bound parameters, so we can equivalently use:</p>
<pre>std:bind(&amp;concat_serveral_times, _1, 3)</pre>

<h3><a name="appendix.bind_vs_lambda.capturing">Capturing variables</a></h3>

<p>In most common cases, when the closure does not outlive the context in which it was created and is invoked in the same
thread of the execution, like when it is passed to STL algorithm, it is safe and optimal to use "capture all be reference"
(<code>[&amp;]</code>) semantics.
For the situation when we want to pass closure, probably wrapped into <code>std::function</code>, outside the current context,
then it is save to use "capture all by value" (<code>[=]</code>) &mdash; but only if we assume that we do not use any unmanaged pointer inside.
However if we want to pass our functor to other thread of execution we need to be sure, that it would not be causing any data races,
and they still may occur if some handler with shallow copy semantics is captured by a lambda (e.g. <code>std::shared_ptr</code>).

<p>The above reasoning leads us to conclusion that when lambda is passed outside current context (either when passing it to other thread, or when returning
it from a function) it is safer to explicitly specify the variables that should be captured. For example, given the following definitions:</p>

<pre>struct Widget { void process(std::string&amp;) const };
struct WidgetFactory { std::unqiue_ptr&lt;Widget&gt; create() };

void process_in_parallel(std::vector&lt;std::string&gt& vs, WidgetFactory&amp; factory)
{
  std::vector&lt;std::future&lt;void&gt;&gt; results;
  for (std::size_t i = 0; i &lt; vs.size(); ++i)
    results.emplace_back(std::async(<em>some_callback</em>));
  for (std::future&lt;void&gt;& fut : results)
    fut.get();
};</pre>

<p>We want to create a callback <code><em>some_callback</em></code> that will process a given element with a concrete widget. 
Our first attempt would be:</p>
<pre>[&amp;vs, &amp;factory, i] { factory.create()-&gt;process(vs[i]); }</pre>

<p>We have accidentally postponed the creation of <code>Widget</code> until the point when lambda is invoked, thus causing
a concurrent invocation of <code>factory</code> method, which could cause a data race. To fix this we might try to create the widget
and capture it from local context:</p>
<pre>
for (std::size_t i = 0; i &lt; vs.size(); ++i)
{
  auto widget = factory.create();
  results.emplace_back(std::async([&amp;vs, widget, i] { widget-&gt;process(vs[i]); }));
}</pre>

<p>The above code will not compile because we want to copy a move-only type <code>std::unique_ptr&lt;Widget&gt;</code>. 
In addition, note that we are capturing the whole vector <code>vs</code>, although it is sufficient to use only one element in a single thread.
Both of this issues may be fixed with a C++14 extended lambda capture:</p>
<pre>[&amp;elem = vs[i], widget = factory.create()] { widget-&gt;process(elem); }</pre>

<p>What it effectively does is to <em>bind</em> (or 'fix') two parameters to a (member) function;
the Standard Library already provides a component designed exactly for such purpose, named <code>std::bind</code>:</p>
<pre>std::bind(&amp;Widget::process, factory.create(), std::ref(vs[i]))</pre>

<p>In contrast to the problem with creating a <code>Widget</code>, it is worth noticing that sometimes it is desired
to capture some precomputed values in lambda. Suppose we want to find an <code>Employee</code> with the given first and
last name:</p>
<pre>std::find_if(std::begin(ve), std::end(ve), [](const auto&amp; e) { return e.full_name() == first + ' ' + last; });</pre>

<p>This innocent-looking code has a performance issue inside: the string <code>first + ' ' + last</code> is constant for every element,
but a new instance is created in every iteration. To avoid such problems we should capture the value:</p>
<pre>std::find_if(std::begin(ve), std::end(ve), [name = first + " " + last](const auto&amp; e) { return e.full_name() == name; });</pre>

<p>Although the use of <code>std::bind</code> would also eliminate the problem, the author recommends
the use of lambda is such case, because nested <code>std::bind</code> (which is necessary in this situation) would render a less readable code:</p>
<pre>std::find_if(std::begin(ve), std::end(ve), std::bind(std::equal_to&lt;&gt;, std::bind(&amp;Employee::full_name, _1), first + ' ' + last));</pre>

<h3><a name="appendix.bind_vs_lambda.summary">Summary</a></h3>

<p>The original aim of the lambda functions was to simplify writing of ad-hoc functors for use with STL algorithms,
and indeed its design makes writing such predicates simple and efficient. As a consequence of such design,
lambda is not efficient when used to write function wrappers. For example, let us compare the following simple
bind expression and its lambda equivalent:</p>

<pre>std::bind(&amp;foo, _1, expr, std::ref(a));
[e = expr, &amp;a] (auto&amp;&amp; arg) -&gt; decltype(auto) { return foo(std::forward&lt;decltype(arg)&gt;(arg), e, a); };</pre>

<p>The use of <code>std::bind</code> to write simple function wrappers allows the programmer to avoid running into correctness
and performance problems described in this appendix. The choice between using <code>bind</code> and a lambda
can be directly compared to the between the use of STL algorithms and writing a raw loop that performs the same
task: both of the solution are feasible, but using the Standard Library is simpler.</p>

<p>Of course, <code>std::bind</code> has its limitations, and should be used only for the simple task of binding
constant values to a specific set of function arguments. If we want to create a function that contains composition 
of the two functions or more complex expression we should use a lambda
or even write a separate function if the expression is large enough. Another drawback of <code>bind</code> is that
if we want to use it with overloaded function name we need resolve the ambiguity at the point of invocation of
<code>std::bind</code> and casting to appropriate function pointer is required.</p>

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

<ol>
  <li>Chris Jefferson, Ville Voutilainen, "Bug 40 - variadic bind" (LEWG Bug 40, <a href="https://issues.isocpp.org/show_bug.cgi?id=40">https://issues.isocpp.org/show_bug.cgi?id=40</a>)</li>
  <li>Mikhail Semenov, "Introducing an optional parameter for mem_fn, which allows to bind an object to its member function" (N3702, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3702.htm">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3702.htm</a>)</li>
  <li>Tomasz Kamiński, Implementation of bind function (<a href="https://github.com/tomaszkam/proposals/tree/master/bind">https://github.com/tomaszkam/proposals/tree/master/bind</a>)</li>
</ol>

</body></html>
