How is tr1::reference_wrapper useful?
Asked Answered
L

2

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?

Lepage answered 11/10, 2008 at 5:36 Comment(0)
R
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. :)

Rite answered 11/10, 2008 at 6:26 Comment(3)
Okay, cool. I'm familiar with boost::ref... I just didn't realize TR1 called this functionality something different - i.e., not tr1::ref.Lepage
@ceretullis ref is the constructor method to produce a reference_wrapper<T> object, where T is a type.Shameful
with C++11, I think I'd prefer to use a lambda: auto fIncrement = [&iVariable]{ Increment(iVariable);};Baleen
S
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

Shameful answered 18/6, 2009 at 8:5 Comment(1)
The "old" syntax is: [A* a_; compared to boost::reference_wrapper<A> a_;] and [a_ = &a; compared to a_ = boost::ref(a);] [return *a_; compared to return a_;] and [B(A& a): a_(a) {} compared to B(A& a): a_(&a) {}]Washer

© 2022 - 2024 — McMap. All rights reserved.