boost::function for functors

It is possible to pass a functor to boost::function, but we should pay some attention in its usage, since the functor is accepted by copy. That means there is no relation between the original functor and the one internally used by the boost::functor object.

Fortunately there is a way to let the boost::functor object to accept a reference to the passed functor, and this requires the usage of boost::ref.

To appreciate the difference between the direct usage of a functor and the one mediated by boost::ref see this example:

#include <iostream>
#include "boost/function.hpp"

using boost::function;
using boost::ref;
using std::cout;
using std::endl;

namespace
{
class KeepingState
{
int total_;
public:
KeepingState() : total_(0) {}

int operator()(int i)
{
total_ += i;
return total_;
}

int total() const
{
return total_;
}
};
}

void function04()
{
KeepingState ks;
function<int(int)> f1;
f1 = ks;

function<int(int)> f2;
f2 = ks;

cout << "Default: functor copied" << endl;
cout << "The current total is " << f1(10) << endl; // 10
cout << "The current total is " << f2(10) << endl; // 10
cout << "The total is " << ks.total() << endl; // 0

cout << "Forcing functor by reference" << endl;
f1 = ref(ks);
f2 = ref(ks);

cout << "The current total is " << f1(10) << endl; // 10
cout << "The current total is " << f2(10) << endl; // 20
cout << "The total is " << ks.total() << endl; // 20
}

The idea is having an instance of a functor (class KeepingState) and passing it to two different boost::function objects. We can check how there is no relation among the three object ks, f1 and f2.

But if we assign the ks object to both f1 and f2 via boost::ref we see how actually always the same object ks is modified by using f1 and f2.

The code is based on an example provided by "Beyond the C++ Standard Library: An Introduction to Boost", by Björn Karlsson, an Addison Wesley Professional book. An interesting reading indeed.

No comments:

Post a Comment