読者です 読者をやめる 読者になる 読者になる

boost::bindとboost::functionをメンバ関数に使う

タイトル通り。

boost::bindメンバ関数を指定すると、第一引数にクラスを引数に取る関数として解釈される。

#include <iostream>

#include <boost/function.hpp>
#include <boost/bind.hpp>

struct LinearExtrapolation {
    LinearExtrapolation(
        const double leftPoint,
        const double leftValue,
        const double rightPoint,
        const double rightValue)
        :
        _leftPoint(leftPoint),
        _leftValue(leftValue),
        _slope((rightValue - leftValue) / (rightPoint - leftPoint)){}
    ~LinearExtrapolation(){};

    //! linear extrapolation.
    double operator() (const double x) const {
        return (x - _leftPoint) * _slope + _leftValue;
    }

    //! differentail of operator()
    double differential(const double x) const {
        return x * _slope;
    }

private:
    const double _leftPoint;
    const double _leftValue;
    const double _slope;
};

/**
 * @brief Functor example.
 */
struct Functor1 {
    double operator() (
        const double time,
        const double state,
        const LinearExtrapolation& extrapolation) const {
        return time * extrapolation(state);
    }
};

/**
 * @brief differetinal of Functor1 w.r.t. state variable.
 */
struct Functor2 {
    double operator() (
        const double time,
        const double state, 
        const LinearExtrapolation& extrapolation) const {
        return time * extrapolation.differential(state);
    }
};


int main(int argc, char const* argv[])
{
    LinearExtrapolation extrapolation(-10.0, -20.0, 10.0, 20.0);
    Functor1 functor1;
    Functor2 functor2;

    boost::function<double (double, double)> function1 = 
        boost::bind(&Functor1::operator(), &functor1, _1, _2, extrapolation);
    boost::function<double (double, double)> function2 = 
        boost::bind(&Functor2::operator(), &functor2, _1, _2, extrapolation);

    std::cout << function1(1.0, 0.0) << std::endl;//output 0
    std::cout << function2(1.0, 2.0) << std::endl;//output 4

    return 0;
}