tag付きtuple

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