<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>A proposal to add a reference wrapper to the standard library</title><meta name="generator" content="DocBook XSL Stylesheets V1.60.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="id2860617"></a>A proposal to add a reference wrapper to the standard library</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Douglas</span> <span class="surname">Gregor <tt class="email">&lt;<a href="mailto:gregod@cs.rpi.edu">gregod@cs.rpi.edu</a>&gt;</tt></span></h3></div></div><div><div class="author"><h3 class="author"><span class="firstname">Peter</span> <span class="surname">Dimov <tt class="email">&lt;<a href="mailto:dimov@mmltd.net">dimov@mmltd.net</a>&gt;</tt></span></h3></div></div></div><div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#ref.intro">Introduction</a></dt><dt><a href="#id2795697">Usage Examples</a></dt><dt><a href="#id2795855">Impact on the standard</a></dt><dt><a href="#id2795919">Proposed Text</a></dt><dd><dl><dt><a href="#header.utility">Header &lt;utility&gt;</a></dt><dt><a href="#header.functional">Header &lt;functional&gt;</a></dt><dt><a href="#id2794293">Additions to &quot;Implemention Quantities&quot;</a></dt></dl></dd><dt><a href="#id2794315">Relationship with other proposals</a></dt><dt><a href="#id2794410">References</a></dt></dl></div><p><b><span class="term">Document number</span></b>:
    N1436=03-0018<br><b><span class="term">Date</span></b>:
    28 February 2003<br><b><span class="term">Project</span></b>:
    Programming Language C++, Library Working Group<br><b><span class="term">Reply-to</span></b>:
    Douglas Gregor <tt class="email">&lt;<a href="mailto:gregod@cs.rpi.edu">gregod@cs.rpi.edu</a>&gt;</tt></p><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ref.intro"></a>Introduction</h2></div></div><div></div></div><p>This proposal defines a small library addition for passing
  references to function templates (algorithms) that would usually
  take copies of their arguments. It defines the class template
  <tt class="computeroutput"><a href="#class.std.reference_wrapper" title="Class template reference_wrapper">reference_wrapper</a></tt> and the two
  functions <tt class="computeroutput"><a href="#id2621250">ref</a></tt> and
  <tt class="computeroutput"><a href="#id2621302">cref</a></tt> that return instances
  of <tt class="computeroutput">reference_wrapper</tt>.</p><p><tt class="computeroutput">reference_wrapper&lt;T&gt;</tt> is a CopyConstructible
  and Assignable wrapper around a reference to an object of type
  <tt class="computeroutput">T</tt>. It provides an implicit conversion to
  <tt class="computeroutput">T&amp;</tt>, often allowing the function templates to work
  on references unmodified. Some library components that would not
  work on references unmodified may instead detect
  <tt class="computeroutput">reference_wrapper</tt> and alter their semantics
  accordingly, e.g., those in the Tuple [<a href="#ref.jarvi02">Jrvi02</a>] and Function Object
  Wrapper [<a href="#ref.gregor02">Gregor02</a>]
  proposals.</p><p>This proposal is based on the Boost.Ref library [<a href="#ref.boost01">Boost01</a>].</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2795697"></a>Usage Examples</h2></div></div><div></div></div><p><tt class="computeroutput"><a href="#class.std.reference_wrapper" title="Class template reference_wrapper">reference_wrapper</a></tt> can be
  used in places where argument deduction would not deduce a
  reference, e.g., when forwarding arguments:</p><pre class="programlisting">void f(int &amp; r)
{
  ++r;
}

template&lt;class F, class T&gt; void g(F f, T t) { f(t); }

int main()
{
  int i = 0;
  g(f, i);
  cout &lt;&lt; i &lt;&lt; endl; // 0
  g(f, ref(i));
  cout &lt;&lt; i &lt;&lt; endl; // 1
}</pre><p>In particular, this can be used to overcome the limitations of
  forwarding constructor arguments:</p><pre class="programlisting">struct X
{
  explicit X(int &amp; r);
};

template&lt;class T&gt; struct wrapper
{
  T t;
  template&lt;class A1&gt; explicit wrapper(A1 const &amp; a1): t(a1) {}
};

int i = 0;
wrapper&lt;X&gt; w1(i); // error
wrapper&lt;X&gt; w1(ref(i)); // OK</pre><p>More information on the forwarding problem is given in [<a href="#ref.dimov02">Dimov02</a>].</p><p><tt class="computeroutput"><a href="#class.std.reference_wrapper" title="Class template reference_wrapper">reference_wrapper</a></tt> can be
  used where ordinary references cannot, e.g., in containers and (by
  way of implicit conversion) function calls that expect the
  underlying type.</p><pre class="programlisting">std::list&lt;int&gt; numbers;
std::vector&lt;<a href="#class.std.reference_wrapper" title="Class template reference_wrapper">reference_wrapper</a>&lt;int&gt; &gt; number_refs;
for(int i = 0; i &lt; 100; ++i) {
  numbers.push_back(4*i*i^2 - 10*i + 3);
  number_refs.push_back(<a href="#id2621250">ref</a>(numbers.back()));
}

std::sort(number_refs.begin(), number_refs.end());</pre><p>Additional examples are given in the Tuple [<a href="#ref.jarvi02">Jrvi02</a>]
  and Function Object Wrapper [<a href="#ref.gregor02">Gregor02</a>] proposals.</p><p><tt class="computeroutput"><a href="#class.std.reference_wrapper" title="Class template reference_wrapper">reference_wrapper</a></tt> contains an
  overloaded function call operator to enable passing function object
  references to standard algorithms. This capability is particularly
  useful for passing function objects that cannot be copied or
  stateful function objects:</p><pre class="programlisting">struct counting_less {
  typedef bool result_type;

  template&lt;typename T&gt; bool operator()(const T&amp; x, const T&amp; y) 
  {
    ++count;
    return x &lt; y;
  }

  int count;
};

// ...

vector&lt;int&gt; elements;
// fill elements
counting_less cl;
sort(elements.begin(), elements.end(), ref(cl));
std::cout &lt;&lt; cl.count &lt;&lt; &quot; comparisons in sort\n&quot;;</pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2795855"></a>Impact on the standard</h2></div></div><div></div></div><p>This proposal defines a pure library extension. A new class
  template <tt class="computeroutput"><a href="#class.std.reference_wrapper" title="Class template reference_wrapper">reference_wrapper</a></tt> is
  proposed to be added to the standard header
  <tt class="computeroutput">&lt;utility&gt;</tt> with two supporting
  functions. Additionally, a class template
  <tt class="computeroutput"><a href="#class.std.result_of" title="Class template result_of">result_of</a></tt> is proposed to be added
  to the standard header <tt class="computeroutput">&lt;functional&gt;</tt>.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2795919"></a>Proposed Text</h2></div></div><div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="header.utility"></a>Header &lt;<a href="../../utility" target="_top">utility</a>&gt;</h3></div></div><div></div></div><pre class="synopsis"><span class="bold"><b>namespace</b></span> std {
<a href="#class.std.reference_wrapper" title="Class template reference_wrapper"><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T&gt; <span class="bold"><b>class</b></span> reference_wrapper;</a>
<a href="#id2621250"><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T&gt; reference_wrapper&lt;T&gt; ref(T&amp;)</a>;
<a href="#id2621302"><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T&gt; reference_wrapper&lt;<span class="bold"><b>const</b></span> T&gt; cref(<span class="bold"><b>const</b></span> T&amp;)</a>;
}</pre><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="class.std.reference_wrapper"></a>Class template reference_wrapper</h4></div></div><div></div></div><pre class="synopsis"><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T&gt; 
<span class="bold"><b>class</b></span> reference_wrapper {
<span class="bold"><b>public</b></span>:
<span class="emphasis"><em>// types</em></span>
<span class="bold"><b>typedef</b></span> T type;

<span class="emphasis"><em>// <a href="#id2620876construct-copy-destruct">construct/copy/destruct</a></em></span>
<a href="#id2620987">reference_wrapper(T&amp;)</a>;

<span class="emphasis"><em>// <a href="#id2621031">access</a></em></span>
<a href="#id2621040"><span class="bold"><b>operator</b></span> T&amp;() <span class="bold"><b>const</b></span></a>;
<a href="#id2621063">T&amp; get() <span class="bold"><b>const</b></span></a>;

<span class="emphasis"><em>// <a href="#id2621086">invocation</a></em></span>
<span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T1, <span class="bold"><b>typename</b></span> T2, ..., <span class="bold"><b>typename</b></span> TN&gt; 
unspecified <a href="#id2621091"><span class="bold"><b>operator</b></span>()</a>(T1&amp;, T2&amp;, ..., TN&amp;) <span class="bold"><b>const</b></span>;
};

<span class="emphasis"><em>// <a href="#id2621242">constructors</a></em></span>
<a href="#id2621250"><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T&gt; reference_wrapper&lt;T&gt; ref(T&amp;)</a>;
<a href="#id2621302"><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T&gt; reference_wrapper&lt;<span class="bold"><b>const</b></span> T&gt; cref(<span class="bold"><b>const</b></span> T&amp;)</a>;</pre><p><tt class="computeroutput">reference_wrapper&lt;T&gt;</tt> is a
      CopyConstructible and Assignable wrapper around a reference to
      an object of type <tt class="computeroutput">T</tt>.</p><p><tt class="computeroutput">reference_wrapper</tt> defines the member type
      <tt class="computeroutput">result_type</tt> in the following cases:
        </p><div class="orderedlist"><ol type="1" compact><li><tt class="computeroutput">T</tt> is a function pointer with C++ linkage, then <tt class="computeroutput">result_type</tt> is the return type of <tt class="computeroutput">T</tt>.</li><li><tt class="computeroutput">T</tt> is a class type with a member type <tt class="computeroutput">result_type</tt>, then <tt class="computeroutput">result_type</tt> is <tt class="computeroutput">T::result_type</tt>.</li></ol></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="id2847270"></a><a name="id2620876construct-copy-destruct"></a><tt class="computeroutput">reference_wrapper</tt> construct/copy/destruct</h5></div></div><div></div></div><div class="orderedlist"><ol type="1"><li><pre class="literallayout"><a name="id2620987"></a>reference_wrapper(T&amp; t);</pre><p><b><span class="term">Effects</span></b>:
    Constructs a
        <tt class="computeroutput"><a href="#class.std.reference_wrapper" title="Class template reference_wrapper">reference_wrapper</a></tt>
        object that stores a reference to
        <tt class="computeroutput">t</tt>.<br><b><span class="term">Throws</span></b>:
    Does not throw.</p></li></ol></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="id2847355"></a><a name="id2621031"></a><tt class="computeroutput">reference_wrapper</tt> access</h5></div></div><div></div></div><div class="orderedlist"><ol type="1"><li><pre class="literallayout"><a name="id2621040"></a><span class="bold"><b>operator</b></span> T&amp;() <span class="bold"><b>const</b></span>;</pre><p><b><span class="term">Returns</span></b>:
    The stored reference.<br><b><span class="term">Throws</span></b>:
    Does not throw.</p></li><li><pre class="literallayout"><a name="id2621063"></a>T&amp; get() <span class="bold"><b>const</b></span>;</pre><p><b><span class="term">Returns</span></b>:
    The stored reference.<br><b><span class="term">Throws</span></b>:
    Does not throw.</p></li></ol></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="id2847464"></a><a name="id2621086"></a><tt class="computeroutput">reference_wrapper</tt> invocation</h5></div></div><div></div></div><div class="orderedlist"><ol type="1"><li><pre class="literallayout"><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T1, <span class="bold"><b>typename</b></span> T2, ..., <span class="bold"><b>typename</b></span> TN&gt; 
unspecified <a name="id2621091"></a><span class="bold"><b>operator</b></span>()(T1&amp; a1, T2&amp; a1, ... , TN&amp; aN) <span class="bold"><b>const</b></span>;</pre><p>[[Author's note: if a form of the move semantics
          proposal [<a href="#ref.hinnant02">Hinnant02</a>] is
          accepted, the parameter types should be rvalue references
          (e.g., <tt class="computeroutput">T1&amp;&amp;</tt>) to properly forward
          arguments.]]</p><p>[[Author's note: the intention of this operator is to
          make <tt class="computeroutput">reference_wrapper&lt;F&gt;</tt> behave in
          function call expressions as if the <tt class="computeroutput">F&amp;</tt>
          conversion operator were used. We hope that future revisions
          of the C++ standard will require this as is currently done
          for user-defined conversions to function pointers.]]</p><p>The return type is the type of the expression
          <tt class="computeroutput">f.get()(a1, a2, ..., aN)</tt>. The implementation
          may deduce this type via any implementation-defined
          means. If the implementation cannot deduce the result of the
          expression <tt class="computeroutput">f.get()(a1, a2, ..., aN)</tt>, the return
          type is <tt class="computeroutput">result_of&lt;T(T1, T2, ...,
          TN)&gt;::type</tt>.</p><p><b><span class="term">Returns</span></b>:
    <tt class="computeroutput">f.get()(a1, a2, ..., aN)</tt></p></li></ol></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"><a name="id2793880"></a><a name="id2621242"></a><tt class="computeroutput">reference_wrapper</tt> constructors</h5></div></div><div></div></div><div class="orderedlist"><ol type="1"><li><pre class="literallayout"><a name="id2621250"></a><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T&gt; reference_wrapper&lt;T&gt; ref(T&amp; t);</pre><p><b><span class="term">Returns</span></b>:
    <tt class="computeroutput"><a href="#class.std.reference_wrapper" title="Class template reference_wrapper">reference_wrapper</a>&lt;T&gt;(t)</tt><br><b><span class="term">Throws</span></b>:
    Does not throw.</p></li><li><pre class="literallayout"><a name="id2621302"></a><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T&gt; reference_wrapper&lt;<span class="bold"><b>const</b></span> T&gt; cref(<span class="bold"><b>const</b></span> T&amp; t);</pre><p><b><span class="term">Returns</span></b>:
    <tt class="computeroutput"><a href="#class.std.reference_wrapper" title="Class template reference_wrapper">reference_wrapper</a>&lt;const T&gt;(t)</tt><br><b><span class="term">Throws</span></b>:
    Does not throw.</p></li></ol></div></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="header.functional"></a>Header &lt;<a href="../../functional" target="_top">functional</a>&gt;</h3></div></div><div></div></div><pre class="synopsis"><span class="bold"><b>namespace</b></span> std {
<a href="#class.std.result_of" title="Class template result_of"><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T&gt; <span class="bold"><b>class</b></span> result_of;</a>
}</pre><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="class.std.result_of"></a>Class template result_of</h4></div></div><div></div></div><pre class="synopsis"><span class="bold"><b>template</b></span>&lt;<span class="bold"><b>typename</b></span> T<span class="emphasis"><em>  // Function type F(A1, A2, ..., An)</em></span>
&gt; 
<span class="bold"><b>class</b></span> result_of {
<span class="bold"><b>public</b></span>:
<span class="emphasis"><em>// types</em></span>
<span class="bold"><b>typedef</b></span> unspecified type;
};</pre><p>The expression <tt class="computeroutput">result_of&lt;F(A1, ...,
      An)&gt;::type</tt>, where <tt class="computeroutput">n</tt> is a nonnegative
      integer and <tt class="computeroutput">F</tt> is a function object type with arity
      <tt class="computeroutput">n</tt>, is intended to yield the type of the expression
      <tt class="computeroutput">f(a1, ..., an)</tt>, where <tt class="computeroutput">f</tt> and
      <tt class="computeroutput">ai</tt> are lvalues of type <tt class="computeroutput">F and <tt class="computeroutput">Ai</tt>,
      respectively.</tt></p><p>The default behavior of <tt class="computeroutput">result_of</tt> is
      implementation defined. Implementations are strongly encouraged
      to supply a functional result of that recognizes functions,
      function pointers, and function objects that have a nested
      typedef <tt class="computeroutput">result_type</tt> as F, and define
      <tt class="computeroutput">result_of&lt;F(...)&gt;::type</tt> accordingly.</p><p><tt class="computeroutput">result_of</tt> can be specialized by users to
      provide a hint to the implementation.</p><p>[[Author's note: this definition of <tt class="computeroutput">result_of</tt>
      is equivalent to the definition in the Bind proposal [<a href="#ref.dimov03">Dimov03</a>]. The uniform return type
      deduction proposal [<a href="#ref.gregor03">Gregor03</a>] further specifies
      <tt class="computeroutput">result_of</tt>.]]</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2794293"></a>Additions to &quot;Implemention Quantities&quot;</h3></div></div><div></div></div><p>Maximum number of arguments forwarded by <tt class="computeroutput">reference_wrapper</tt> [10]</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2794315"></a>Relationship with other proposals</h2></div></div><div></div></div><p>Class template <tt class="computeroutput">reference_wrapper</tt> and function
  templates <tt class="computeroutput">ref</tt> and <tt class="computeroutput">cref</tt> were also defined
  in the Function object wrappers [<a href="#ref.gregor02">Gregor02</a>] and Tuple [<a href="#ref.jarvi02">Jrvi02</a>] proposals . The
  definition in this proposal is compatible with the definitions in
  both these proposals; this proposal is meant only to clarify the
  role of <tt class="computeroutput">reference_wrapper</tt> and its helper functions, as
  requested by the committee, and also to extend its abilities as a
  function object.</p><p>Class template <tt class="computeroutput">result_of</tt> is also introduced in
  the Bind proposal [<a href="#ref.dimov03">Dimov03</a>] with
  the same proposed text, and forms the basis for the uniform result
  type deduction proposal [<a href="#ref.gregor03">Gregor03</a>].</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id2794410"></a>References</h2></div></div><div></div></div><p><a name="ref.jarvi02"></a>[Jrvi02] Jaakko Jrvi,
  <span class="emphasis"><em>Proposal for adding tuple types into the standard
  library</em></span>, C++ committee document N1403=02-0061, November
  2002. Available online at <a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1403.pdf" target="_top">http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1403.pdf</a></p><p><a name="ref.gregor02"></a>[Gregor02] Douglas Gregor, <span class="emphasis"><em>A
  Proposal to add a Polymorphic Function Object Wrapper to the
  Standard Library</em></span>, C++ committee document N1402=02-0060,
  October 2002. Available online at <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1402.htm" target="_top">http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1402.htm</a>.</p><p><a name="ref.dimov02"></a>[Dimov02] Peter Dimov, Howard E. Hinnant, Dave
  Abrahams, <span class="emphasis"><em>The Forwarding Problem: Arguments</em></span>,
  C++ committee document N1385=02-0043, September 2002. Available
  online at <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_top">http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm</a></p><p><a name="ref.boost01"></a>[Boost01] Boost.Ref library, 2001. Available
  online at <a href="http://www.boost.org/libs/bind/ref.html" target="_top">http://www.boost.org/libs/bind/ref.html</a></p><p><a name="ref.hinnant02"></a>[Hinnant02] Howard E. Hinnant, Peter Dimov,
  and Dave Abrahams, <span class="emphasis"><em>A Proposal to Add Move Semantics Support
  to the C++ Language</em></span>, C++ committee document
  N1377=02-0035, September 2002. Available online at <a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm" target="_top">http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1377.htm</a>.</p><p><a name="ref.dimov03"></a>[Dimov03] Peter Dimov, Douglas Gregor, Jaakko
  Jrvi, and Gary Powell, <span class="emphasis"><em>A Proposal to Add an Enhanced
  Binder to the Library Technical Report</em></span>, C++ committee
  document N1438=03-0020, February 2003. Available online at <a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1438.html" target="_top">http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1438.html</a>.</p><p><a name="ref.gregor03"></a>[Gregor03] Douglas Gregor, <span class="emphasis"><em>A
  Uniform Method for Computing Function Object Return
  Types</em></span>, C++ committee document N1437=03-0019, February
  2003. Available online at <a href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1437.htm" target="_top">http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1437.htm</a>.</p></div></div></body></html>
