C++0 x変長パラメータテンプレートを使用してメタグループを実現
3806 ワード
最近,C++0 xに関する問題を検討し,GCC 4.6で変長パラメータテンプレートを用いてメタグループを実現した.
使用方法:
template<typename ... AllTypes>
struct MyTuple;
template<> struct MyTuple<> {};
template<int N, class T>
struct ElementType;
template<typename Head, typename ... Tail>
struct MyTuple<Head,Tail...>
{
MyTuple(Head h, Tail... t)
: tail(t...)
, head(h)
{
}
MyTuple(const MyTuple<Head,Tail...>& t)
: tail(t.tail)
, head(t.head)
{
}
MyTuple(MyTuple<Head,Tail...>&& t)
: tail(t.tail)
, head(t.head)
{
}
MyTuple<Tail...> tail;
Head head;
typedef Head HeadType;
typedef MyTuple<Tail...> TailType;
};
//
template <int k>
struct get_class {
template <typename Head, typename ... Tail>
static typename ElementType<k,MyTuple<Head,Tail...> >::type& get(MyTuple<Head,Tail...>& t )
{
return get_class<k-1>::get(t.tail);
}
template <typename Head, typename ... Tail>
static const typename ElementType<k,MyTuple<Head,Tail...> >::type& get(const MyTuple<Head,Tail...>& t )
{
return get_class<k-1>::get(t.tail);
}
};
template <>
struct get_class<0> {
template <typename Head, typename ... Tail>
static typename MyTuple<Head,Tail...>::HeadType& get(MyTuple<Head,Tail...>& t )
{
return t.head;
}
template <typename Head, typename ... Tail>
static const typename MyTuple<Head,Tail...>::HeadType& get(const MyTuple<Head,Tail...>& t )
{
return t.head;
}
};
//
template<int N, class T>
struct ElementType
{
private:
typedef typename T::TailType Next;
public:
typedef typename ElementType<N-1, Next>::type type;
};
template<class T>
struct ElementType<0, T>
{
typedef typename T::HeadType type;
};
template < int k,typename Head, typename ... Tail>
typename ElementType<k,MyTuple<Head,Tail...> >::type& get(MyTuple<Head,Tail...>& t)
{
return get_class<k>::get(t);
}
template < int k,typename Head, typename ... Tail>
const typename ElementType<k,MyTuple<Head,Tail...> >::type& get(const MyTuple<Head,Tail...>& t)
{
return get_class<k>::get(t);
}
使用方法:
MyTuple<double,int,double,int,string,const char*> t(2.1,0,1.11,6666,"helloworld z","world");
cout << get<0>(t) << get<1>(t) << get<2>(t) << get<3>(t) << get<4>(t) << get<5>(t) << std::endl;
get<0>(t) = 100;
get<1>(t) = 10;
get<4>(t) = "gg world";
const MyTuple<int,int,double,int,string> tc(0,0,111.1,5555,"helloworld");
cout << get<0>(tc) << get<1>(tc) << get<2>(tc) << get<3>(tc) << get<4>(tc) << std::endl;
cout << get<1>( MyTuple<double,char>(3.1415926,'c')) << std::endl;