Question

I have the following code that compiles thanks to boost's bind facility to pass a non-static member function as parameter where a global function parameter is expected. Note that I'm omitting a lot of details but my use-case is simply to pass a non-static member function as parameter and I need a typedef for this function, see the code comments in the snippet below:

#include <boost/tuple/tuple.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <Eigen/Dense>

// ridge solver using conjugate gradient
template <>
inline void SomeANN<kConjugateGradient>::ridge_solve(const VectorXd& Y) {
    // horrendous typedef I'd like to get rid of
    typedef _bi::bind_t<tuples::tuple<double, VectorXd >, 
      _mfi::mf1<tuples::tuple<double, VectorXd>,
        SomeANN<(Minimizer)1u>, const VectorXd&>, _bi::list2<_bi::value<SomeANN<(Minimizer)1u>*>,  
          boost::arg<1> > > oracle_f;
    // I'd prefer this typedef instead of the ugly one above but doesn't compile
    //typedef tuple<double, VectorXd> (SomeANN<kConjugateGradient>::*oracle_f)(const VectorXd&);
    ConjugateGradient<BeginSpace, VectorXd, oracle_f> optimizer;
    // ...
    optimizer.search(BeginSpace(Y.rows()), boost::bind(&SomeANN<kConjugateGradient>::f, this, ::_1));
}

// definition of f. I need to pass this function as parameter to CG
template <>
inline tuple<double, VectorXd> SomeANN<kConjugateGradient>::f(const VectorXd& theta) {
    // TODO: implement properly
    double f = 0.0;
    VectorXd df;
    return make_tuple(f, df);
}

but the typedef that I use above that I took from a previous error message is mega-ugly and would like to use something more readable like the line commented typedef tuple<double, VectorXd> (SomeANN<kConjugateGradient>::*oracle_f)(const VectorXd&); but it will not compile. I need a typedef for oracle_f to be able to specify the correct template parameter in the declaration ConjugateGradient<BeginSpace, VectorXd, oracle_f> optimizer;.

Was it helpful?

Solution 2

How about use boost::function?

typedef boost::function<tuples::tuple<double, VectorXd>(const VectorXd&)> oracle_f;

OTHER TIPS

Sorry, but without C++11's decltype or auto, you're stuck with either using the big ugly type (which is an implementation detail of Boost.Bind, really), or else using boost::function to erase the type, which incurs the cost of indirection on every call.

Wasn't search itself the template in your previous question?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top