21

recently I've been reading through Scott Meyers's excellent Effective C++ book. In one of the last tips he covered some of the features from TR1 - I knew many of them via Boost.

However, there was one that I definitely did NOT recognize: tr1::reference_wrapper.

How and when would I use tr1::reference_wrapper?

oz10
  • 153,307
  • 27
  • 93
  • 128

2 Answers2

17

It's like boost::ref, as far as I know. Basically, a reference which can be copied. Very useful when binding to functions where you need to pass parameters by reference.

For example (using boost syntax):

void Increment( int& iValue )
{
    iValue++;
}

int iVariable = 0;
boost::function< void () > fIncrementMyVariable = boost::bind( &Increment, boost::ref( iVariable ));

fIncrementMyVariable();

This Dr. Dobbs article has some info.

Hope this is right, and helpful. :)

pmr
  • 58,701
  • 10
  • 113
  • 156
Nick
  • 6,808
  • 1
  • 22
  • 34
  • Okay, cool. I'm familiar with boost::ref... I just didn't realize TR1 called this functionality something different - i.e., not tr1::ref. – oz10 Oct 11 '08 at 15:53
  • 2
    @ceretullis ref is the constructor method to produce a reference_wrapper object, where T is a type. – amit kumar Jun 18 '09 at 07:40
  • with C++11, I think I'd prefer to use a lambda: `auto fIncrement = [&iVariable]{ Increment(iVariable);};` – Chris Drew May 11 '16 at 05:28
11

reference_wrapper<T> is an immensely useful and simple library. Internally the reference_wrapper<T> stores a pointer to T. But the interface it exposes does not contain any pointer notation.

  • It allows the reference to behave like other simple objects - a reference_wrapper<T> can be stored in a STL container.
  • It helps avoid the dreadful pointer notation - the cause of so many segmentation faults. Replace a pointer to T with a reference_wrapper<T>, pointers by references and T->f() by T.f() wherever possible (ofcourse pointers need to be stored for deleting a heap-allocated objects, but for memory management Boost Pointer Containers are quite useful).

Example:

class A
{
    //...
};

class B
{
 public:
   void setA(A& a) 
   {
     a_ = boost::ref(a); // use boost::cref if using/storing const A&
   }
   A& getA()
   {
      return a_;
   }
   B(A& a): a_(a) {}
private:
   boost::reference_wrapper<A> a_; 
};

int main()
{
   A a1;
   B b(a1);
   A a2;
   b.setA(a2);
   return 0;
}

Here I have used the boost implementation of reference wrapper, but C++0x standard is going to have it too. See also http://aszt.inf.elte.hu/~gsd/halado_cpp/ch11.html#Bind-ref

amit kumar
  • 20,438
  • 23
  • 90
  • 126