matII
matII

Reputation: 21

How to store boost::bind object as member variable?

I am using boost::bind to create composed functions on-the-fly, and hope to store the object as some class member variable for later usage. For example we have two functors:

struct add{double operator()(double x, double y) const{return x+y;};};  
struct multiply{double operator()(double x, double y) const{return x*y;};};  

Then to create a function f(x,y,z) = (x+y)*z, I can do this:

auto f = boost::bind<double>(multiply(), boost::bind<double>(add(), _1, _2), _3);

And calling f(x,y,z) works perfectly. Now I want to save f as a class member variable, something like the following:

struct F  
{  
  auto func;  
  double operator(const std::vector<double>& args) const  
  {  
    return func(args[0],args[1],args[2]); //Skipping boundary check  
  }  
}

F f_obj;  
f_obj.func = f;  
f_obj(args);  

But of course I cannot declare an auto variable. Is there any way to get around this?

Note that I am not using boost::function, as it will dramatically impact the performance, which is important to me.

Thanks for any advice.

Upvotes: 2

Views: 685

Answers (2)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 154035

The type returned from bind() is specific to each combination of function objects and arguments. If you want to store the result, you will need to erase the type in some way. The obvious approach is to use function<..>.

When the resulting function object is invoked frequently, the overhead introduced by function<...> effectively doing a virtual dispatch may be too high. One approach to counter the problem is to bundle the function object with suitable bulk operations and instead of storing the function object to store a suitable application. That won't help when individual calls are needed but when lots of calls are required the virtual dispatch is paid just once.

Upvotes: 3

Alan Stokes
Alan Stokes

Reputation: 18972

Two options: use boost::function, and measure whether it actually affects performance.

Alternatively make F a template taking the type of func as parameter and deduce it from the type of the bind expression.

EDIT: The problem with the second option is it doesn't get rid of the awkward type. You can do that by defining a base class with a pure virtual function which the template overrides. But then you have dynamic memory to manage and the cost of a virtual function to pay - so you might as well go back to boost::function (or std::function) which does much the same thing for you.

Upvotes: 5

Related Questions