eugene
eugene

Reputation: 41745

Use boost::function as function argument?

I want to call a function foo and let it behave differently.
(I'm adopting Strategy or Command pattern. They look similar to me.)

My overall plan is as follows..

First, define foo to take boost::function type

foo(boost::function<someType> execFunction)
{
// do something 
execFunction(args);
// do something
}

Then, I give foo() different functions(as argument) depending on what I want.

Would this work? or Would you advise against it?
Any comments are welcome.

edit

Minor related question is, sometimes execFunction needs 1 argument, and other times it needs 2 arguments.

I could use boost::function for both cases and just ignore the 2nd argument when not needed.
Is there a cleaner way to do this?

Upvotes: 1

Views: 4304

Answers (2)

pmr
pmr

Reputation: 59841

This works very well. But sometimes it is preferable to work with a functor so your callers are free to choose what is best for them and to prevent the smalll overhead that comes with a boost::function:

template<typename Func>
void foo(Func f) {
  f(myArgs);
}

You can also add an overload for the specific boost::function to take the object by reference.

template<>
void foo(const boost::function<void (expectedtypes)>& f) {
  f(myArgs);
}

And possibly have that overloaded for constness as well.

For the case of accepting boost::function objects of different arity, I'd use overloading. If you go that route, avoid the templated version as you are going to run into trouble as soon as your users try to work with functors (as opposed to boost::function with different arity). This trouble is resolvable, but can get messy. You would need to dispatch the call to something that detects the arity of the funtor and executes the proper call. But as you said that templates are your weak-point, this isn't really recommended.

Upvotes: 4

That is a common pattern, and will work. I have used that in the past and will most probably use it in the future. I try to use it only in some specific use cases, as it reduces drastically coupling, and while that is good in general, it makes it harder to follow the flow of control from the code (i.e. if you abuse it, it will be really hard to find what your program is meant to do other than running it in the debugger). But for specific tasks it is fine.

If you do not need to store the function<> for later use, or any runtime polymorphic behavior on the callee side, you can also consider using a function template, so that callers don't need to convert to function<> before executing your function.

Upvotes: 0

Related Questions