variadic templates なクラス
std::tuple を見ながら徐々に tuple を実装して variadic templates なクラスの書き方を知ろう的な.
tuple
はじめのいっぽ.
http://ideone.com/kKSxW
これだと不便すぎるので I 番目の要素にアクセスする方法が欲しい.
そこで各 tuple_impl に数字でタグを付けてそれで区別できるようにする.
template <int I, class ...Ts> struct tuple_impl; template <int I> struct tuple_impl<I> {}; template <int I, class T, class ...Ts> struct tuple_impl<I, T, Ts...> : public tuple_impl<I+1, Ts...> { T value; }; template <class ...Ts> struct tuple : public tuple_impl<0, Ts...> {};
するとまず tuple の I 番目の要素の型を返すメタ関数は次のように定義し,
template <int I, class ...Ts> struct tuple_element; template <class T, class ...Ts> struct tuple_element<0, T, Ts...> { typedef T type; }; template <int I, class T, class ...Ts> struct tuple_element<I, T, Ts...> { typedef typename tuple_element<I-1, Ts...>::type type; };
tuple の I 番目の要素の参照を返す関数 get を次のように定義できる.
template <int I, class T, class ...Ts> T& get_impl(tuple_impl<I, T, Ts...>& t) { return t.value; } template <int I, class ...Ts> typename tuple_element<I, Ts...>::type& get(tuple<Ts...>& t) { return get_impl<I>(t); }
適当にコンストラクタを定義し,make_tuple できるようにする.
http://ideone.com/kX2l8
boost::compressed_pair 的なこともしてみる.std::tuple もこんなかんじになっていた.
http://ideone.com/1jF0d
最初 tuple_impl_base のほうには数字のタグを持たせなくてもいいんじゃ? と思ったけど,同じ型を複数持つようなタプルの場合に base_type が曖昧になってダメなことに気付いた.