Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between boost::ref and regular references

What is the difference between boost::ref(i) and & i ? What are the situations where we cannot use regular references and have to go for boost::ref instead? Please include examples if possible.

like image 468
Venkat Shiva Avatar asked Apr 01 '10 14:04

Venkat Shiva


2 Answers

From the Boost.Ref Documentation:

The purpose of boost::reference_wrapper is to contain a reference to an object of type T. It is primarily used to "feed" references to function templates (algorithms) that take their parameter by value.

NB: An important difference between boost::reference_wrapper and std::reference_wrapper (at least of Boost 1.52) is the ability of std::reference_wrapper to perfectly wrap function objects.

This enables code like this:

// functor that counts how often it was applied
struct counting_plus {
  counting_plus() : applications(0) {}
  int applications;

  int operator()(const int& x, const int& y) 
  { ++applications; return x + y; }
};

std::vector<int> x = {1, 2, 3}, y = {1, 2, 3}, result;
counting_plus f;
std::transform(begin(x), end(x), begin(y), 
               std::back_inserter(result), std::ref(f));
std::cout << "counting_plus has been applied " << f.applications 
          << " times." << '\n';
like image 109
pmr Avatar answered Oct 16 '22 11:10

pmr


In Boost.Thread for example :

A new thread is launched by passing an object of a callable type that can be invoked with no parameters to the constructor. The object is then copied into internal storage, and invoked on the newly-created thread of execution. If the object must not (or cannot) be copied, then boost::ref can be used to pass in a reference to the function object. In this case, the user of Boost.Thread must ensure that the referred-to object outlives the newly-created thread of execution.

Code from doc :

struct callable
{
    void operator()();
};

boost::thread copies_are_safe()
{
    callable x;
    return boost::thread(x);
} // x is destroyed, but the newly-created thread has a copy, so this is OK

boost::thread oops()
{
    callable x;
    return boost::thread(boost::ref(x));
} // x is destroyed, but the newly-created thread still has a reference
  // this leads to undefined behaviour
like image 4
anno Avatar answered Oct 16 '22 12:10

anno