tags:

views:

899

answers:

2

Hi, 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?

+5  A: 

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. :)

Nick
Okay, cool. I'm familiar with boost::ref... I just didn't realize TR1 called this functionality something different - i.e., not tr1::ref.
ceretullis
@ceretullis ref is the constructor method to produce a reference_wrapper<T> object, where T is a type.
Amit Kumar
+1  A: 

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 and a reference_wrapper member can be instantiated even later than the constructor.
  • 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%5Fcpp/ch11.html#Bind-ref

Amit Kumar