最近有空研究了一下C++0x相关的问题,并且在GCC4.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;