Boost.Fusionでは、様々なデータ構造のタプルが提供され、
それらのタプルに対して使用できるSTLライクなアルゴリズムも提供されています。
たとえば、タプルの全要素を出力するには以下のように書きます。
#include <iostream> #include <string> #include <boost/fusion/container/vector.hpp> #include <boost/fusion/algorithm.hpp> struct disper { // パラメータの型が毎回変わる(int, double, std::string)のでテンプレートにする template <class T> void operator()(const T& x) const { std::cout << x << std::endl; } }; int main() { using namespace boost::fusion; vector<int, double, std::string> p(24, 3.14, "Akira"); for_each(p, disper()); }
24 3.14 Akira
これだけでもかなり便利ですが、Boost.Fusionでは、ユーザー定義のクラスに対して
Fusionのアルゴリズムを適用する手段も提供してくれています。
たとえば、以下のpersonクラスの場合には
struct person { int id; int age; std::string name; person(int id, int age, const std::string& name) : id(id), age(age), name(name) {} };
以下のようなマクロを書きます。
#include <boost/fusion/adapted/struct/adapt_struct.hpp> BOOST_FUSION_ADAPT_STRUCT ( person, (int, id) (int, age) (std::string, name) )
これだけで、personクラスをBoost.Fusionのコンテナとして使用できます。
person p(1, 24, "Akira"); boost::fusion::for_each(p, disper());
1 24 Akira
Boost.Fusionのiterator_facadeとsequence_facadeも試してみましたが
そっちだとどうしてもコード量がかなり多くなってしまうのが、
この方法だとマクロ一発流すだけなのでとてもお手軽です。
ちなみに、BOOST_FUSION_ADAPT_STRUCTでアダプトされた型はランダムアクセスシーケンスになります。
以下、全ソース
#include <iostream> #include <string> #include <boost/fusion/algorithm.hpp> #include <boost/fusion/adapted/struct/adapt_struct.hpp> struct person { int id; int age; std::string name; person(int id, int age, const std::string& name) : id(id), age(age), name(name) {} }; BOOST_FUSION_ADAPT_STRUCT ( person, (int, id) (int, age) (std::string, name) ) struct disper { template <class T> void operator()(const T& x) const { std::cout << x << std::endl; } }; int main() { person p(1, 24, "Akira"); boost::fusion::for_each(p, disper()); }
【参照】
BOOST_FUSION_ADAPT_STRUCT - Boost C++ Libraries