chained inheritanceによって,各データフィールドをtag dispatchされたgetterによって取得できるtuple.
class empty_tuple { public: empty_tuple(){ } empty_tuple(empty_tuple const &r){ } void get(){ } }; template<class T, class Tag, class Derived = empty_tuple> class tagged_tuple : public Derived { public: tagged_tuple() : Derived(), val(){ } tagged_tuple(tagged_tuple const &r) : Derived(r), val(r.val){ } using Derived::get; T &get(Tag){ return val; } T const &get(Tag) const{ return val; } private: T val; };
予想以上に短かく書けちゃった.
boost::propertyのパクりというかほとんどそのまんま.boost::propertyの実装ではだいたいこんなことをしてますよっていう紹介だけ.
boost::propertyのようにgetterをfree-standingにした方がきれいな予感.
ちなみに下のような感じで使えまふ.
#include <string> #include <iostream> struct name_tag{ }; struct age_tag{ }; struct weight_tag{ }; struct height_tag{ }; int main() { typedef tagged_tuple<std::string, name_tag, tagged_tuple<int, age_tag, tagged_tuple<double, weight_tag, tagged_tuple<double, height_tag> > > > personal_data; personal_data d; d.get(name_tag()) = "Cryolite"; d.get(age_tag()) = 24; d.get(weight_tag()) = 58.3; d.get(height_tag()) = 174.3; std::cout << "name: " << d.get(name_tag()) << std::endl; std::cout << "age: " << d.get(age_tag()) << std::endl; std::cout << "weight: " << d.get(weight_tag()) << std::endl; std::cout << "height: " << d.get(height_tag()) << std::endl; return EXIT_SUCCESS; }