
Kirit Sælensminde wrote:
typedef result_of_curry2<int (*)(int, int)>::type T_curried_plus; T_curried_plus const curried_plus = BOOST_EGG_CURRY2(&::plus);
The template type for the result of curry is a useful utility. Do you need the arity of the function in the name though? Can this not be done through template specialisation, or does that get too hairy on a few compilers?
FunctionObject can be overloaded with different arities. Another problem is that non-numbered form of macro is clearly impossible. But non-numbered function `curry` could be added for the famous FunctionObjects, e.g, function-pointer and boost::function<> etc.
It might also be nice if it took the function type in the same way that boost::function does, i.e. int (int, int) rather than int (*)(int, int).
result_of_curry2 takes any PolymorphicFunctionObject type. It seems not so good idea to admit function pointers as special case, because function pointers are a minority in FunctionObjects.
And finally, does the curry function itself need to be a macro?
When you need static-initialization. BOOST_EGG_CURRY2(..) is, in fact, a knotty braced initializer, which guarantees static-initialization. Of course, Egg supports also: typedef boost::result_of<T_curry2(int(*)(int,int))>::type T_curried_plus; T_curried_plus curried_plus = curry2(&::plus); No macros. But there is a function-call, which incurs dynamic-initialization. You might notice that "static form" using macro and "dynamic form" using function is nicely symmetric.
Here is my implementation of curry2. I'd always assumed that a complete implementation would overload on the relevant "callable" types:
As mentioned above, non-numbered form `curry` might support the famous "callables". It seems difficult to define "what is famous", though. Regards, -- Shunsuke Sogame