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;
}