I have such template functions:
template<class R> list<R> f(const boost::function<R()>&);
template<class R, class A0> list<R> f(const boost::function<R(T0)>&, list<A0>);
template<class R, class A0, class A1> list<R> f(const boost::function<R(T0)>&, list<A0>, list<A1>);
To run one of them i need to write for example:
int one() { return 1; }
int inc(int x) { return x + 1; }
list<int> l;
f<int>(one);
f<int, int>(inc, l);
And my goal is to just write:
f(one);
f(inc, l);
I heard that this is possible by some kind of template signature specialization, but I can’t figure out how.
Without C++11, you can’t get away from specifying a return type of a function.
With the new C++11 features you can though.
You can template the function/functor as a parameter, instead of trying to specify that it has to be a boost::function.
This lets you pass in the function pointer rather simply.
If you need to actually use functions or bind you can pass that in to the same interface.
As well as with a functor, which is typical for passing in strict weak ordering behavior to the standard containers.
It doesn’t have to check the type of what you pass in to it, only that it satisfies the interface. This is one of the reasons C++ templates are typically much more powerful than generics in other languages.
And for completeness… If you actually did want to restrict it to boost::function, here is an example.
Update:
boost::bind works out of the box, with this, although the raw function pointers have more of a problem. foo is ambiguous there.
If you fully specify the function pointer then it works, though that isn’t what anyone wants to do.
With boost::bind as evidence, You should be able to determine the arity from the calling convention of
f. If I get some time today I’ll play with it.