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

BOOST_FUSION_ADAPT_CLASS

C++

ユーザー定義構造体をBoost.FusionのシーケンスとしてアダプトするためのBOOST_FUSION_ADAPT_CLASSマクロがありますが、これはメンバ変数がpublicである場合のみ使用できます。
privateなメンバ変数とゲッタ/セッタはあるから、それらを使ってユーザー定義クラスをBoost.Fusionのシーケンスとしてアダプトしたい、という場合に、BOOST_FUSION_ADAPT_CLASSを使用することでアダプトできます。

#include <iostream>
#include <boost/fusion/include/algorithm.hpp>
#include <boost/fusion/include/adapt_class.hpp>
#include <boost/fusion/include/as_vector.hpp>

namespace fusion = boost::fusion;

class point {
    int x_, y_;
public:
    point(int x, int y) : x_(x), y_(y) {}

    int get_x() const { return x_; }
    int get_y() const { return y_; }
    void set_x(int x) { x_ = x; }
    void set_y(int y) { y_ = y; }
};

BOOST_FUSION_ADAPT_CLASS(
    point,
    (int, int, obj.get_x(), obj.set_x(val))
    (int, int, obj.get_y(), obj.set_y(val))
);

struct disp {
    template <class T>
    void operator()(const T& x) const
    {
        std::cout << x << std::endl;
    }
};

int main()
{
    point p(1, 2);
    fusion::for_each(fusion::as_vector(p), disp());
}
1
2

注意すべき点は、

  • ゲッタ/セッタのレシーバをobjという名前にすること。
  • セッタの引数をvalにすること。
  • アルゴリズムを適用する場合、as_vectorしないとうまくいかない

といった点です。
Boost 1.44.0時点でこのマクロがまだアンドキュメントであることから、最後の一点についてはまだ未完成なのかもしれないと考えられます。