Document number:
N1453=03-0036
Revises document number:
N1436=03-0018
Date:
9 April 2003
Project:
Programming Language C++, Library Working Group
Reply-to:
Doug Gregor <gregod@cs.rpi.edu>
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 reference_wrapper and the two functions ref and cref that return instances of reference_wrapper.
reference_wrapper<T> is a CopyConstructible and Assignable wrapper around a reference to an object of type T. It provides an implicit conversion to T&, often allowing the function templates to work on references unmodified. Some library components that would not work on references unmodified may instead detect reference_wrapper and alter their semantics accordingly, e.g., those in the Tuple and Function Object Wrapper proposals.
This proposal is based on the Boost.Ref library.
reference_wrapper can be used in places where argument deduction would not deduce a reference, e.g., when forwarding arguments:
void f(int & r) { ++r; } template<class F, class T> void g(F f, T t) { f(t); } int main() { int i = 0; g(f, i); cout << i << endl; // 0 g(f, ref(i)); cout << i << endl; // 1 }
In particular, this can be used to overcome the limitations of forwarding constructor arguments:
struct X { explicit X(int & r); }; template<class T> struct wrapper { T t; template<class A1> explicit wrapper(A1 const & a1): t(a1) {} }; int i = 0; wrapper<X> w1(i); // error wrapper<X> w1(ref(i)); // OK
More information on the forwarding problem is given in N1385.
reference_wrapper can be used where ordinary references cannot, e.g., in containers and (by way of implicit conversion) function calls that expect the underlying type.
std::list<int> numbers; std::vector<reference_wrapper<int> > number_refs; for(int i = 0; i < 100; ++i) { numbers.push_back(4*i*i^2 - 10*i + 3); number_refs.push_back(ref(numbers.back())); } std::sort(number_refs.begin(), number_refs.end());
Additional examples are given in the Tuple and Function Object Wrapper proposals.
reference_wrapper 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:
struct counting_less { typedef bool result_type; template<typename T> bool operator()(const T& x, const T& y) { ++count; return x < y; } int count; }; // ... vector<int> elements; // fill elements counting_less cl; sort(elements.begin(), elements.end(), ref(cl)); std::cout << cl.count << " comparisons in sort\n";
This proposal defines a pure library extension. . A new class template reference_wrapper is proposed to be added to the standard header <utility> with two supporting functions.
namespace std { template<typename T> class reference_wrapper; template<typename T> ref(T&); template<typename T> cref(const T&); }
std::reference_wrapper — Contains a reference to an object of type T.
template<typename T> class reference_wrapper { public: // types typedef T type; // construct/copy/destruct explicit reference_wrapper(T&); // access operator () const; get() const; // invocation template<typename T1, typename T2, ..., typename TN> typename result_of<T(T1, T2, ..., TN)>::type operator()(T1, T2, ..., TN) const; }; // constructors template<typename T> ref(T&); template<typename T> cref(const T&);
reference_wrapper<T> is a CopyConstructible and Assignable wrapper around a reference to an object of type T.
reference_wrapper defines the member type result_type in the following cases:
explicit reference_wrapper(T& t);
Effects:
Constructs a
reference_wrapper
object that stores a reference to
t.
Throws:
Does not throw.
template<typename T> ref(T& t);
Returns:
reference_wrapper<T>(t)
Throws:
Does not throw.
template<typename T> cref(const T& t);
Returns:
reference_wrapper<const T>(t)
Throws:
Does not throw.
Class template reference_wrapper and function templates ref and cref were also defined in documents N1402 (Function object wrappers) and N1403 (Tuples). The definition in this proposal is compatible with the definitions in both these proposals; this proposal is meant only to clarify the role of reference_wrapper and its helper functions, as requested by the committee.
Much of the text of this proposal comes from the Boost.Ref library documentation written by Peter Dimov. The first two examples were presented by Peter Dimov in c++std-ext-5635.
Järvi, Jaakko. Proposal for adding tuple types into the standard library. http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1403.pdf
Gregor, Doug. A Proposal to add a Polymorphic Function Object Wrapper to the Standard Library. http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1402.html
Dimov, Peter. The Forwarding Problem: Arguments. http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
The Boost.Ref Library. http://www.boost.org/libs/bind/ref.html