Reputation: 41745
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.
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
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
Reputation: 208446
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