
AMDG jesseperla wrote:
Stephen: Thanks as always, a few follow-ups:
Err, I usually spell my name with a 'v'
Question 3: How would we adapt a structure implementing the operator() and gradient() to be stored here? Just like boost::function accepting any function object? struct square { double operator()(double x) {return x * x;} double gradient(double x){return 2 * x;} }; math_function
myfunc(square); template<class F> math_function(const F& f) : f_(f), g_(bind(F::gradient, f, _1...?) //Here I don't see how to bind to the arbitrary signature, extracting the inputs from the Signature which (may) be more than 1
You'll have to either specialize math_function for different arities or push the construction of the function that holds the gradient into a separate class which is specialized for each arity or use a custom function object that contains all the overloads of operator() needed instead of Boost.Bind.
However, it is fairly easy to give math_function members that return these traits at runtime.
Is there a canonical example of a way to do this the best way?
It's pretty straightforward: // default implementation template<class T> bool is_convex(const T& t) { return(false); } // overload for math_function template<class S> bool is_convex(const math_function<S>& m) { return(m.is_convex()); } // overloads for other objects should be found by ADL. template<class S> class math_function { // ... math_function(F f) : is_convex_(is_convex(f)) {} bool is_convex_; }; This is the simplest solution. Of course, if necessary, you can use more type erasure to delay the calculation of is_convex until its needed. In Christ, Steven Watanabe