c++的tuple可以装载任何的类型,用法示例:
std::tuple<int, char> a(10, 'x'); std::cout << " " << std::get<0>(a); std::cout << " " << std::get<1>(b);
先上一个极简的tuple实现
#include <stdio.h> template <typename... Types> struct mytuple { }; template <typename T, typename... Types> struct mytuple<T, Types...> : mytuple<Types...>{ mytuple(T v, Types... args) : _val(v), mytuple<Types...>(args...) { } T _val; }; template <typename T> struct mytuple<T> { mytuple(T v) : _val(v) { } T _val; }; template <size_t n, typename... Types> struct mytuple_element { }; template <size_t n, typename T, typename... Types> struct mytuple_element<n, T, Types...> { typedef typename mytuple_element<n - 1, Types...>::type type; typedef typename mytuple_element<n - 1, Types...>::tuple_type tuple_type; }; template <typename T, typename... Types> struct mytuple_element<0, T, Types...> { typedef T type; typedef mytuple<T, Types...> tuple_type; }; template<size_t n, typename... Types> typename mytuple_element<n, Types...>::type myget(const mytuple<Types...>& tup) { return ((typename mytuple_element<n, Types...>::tuple_type&)tup)._val; } int main() { mytuple<int, float, char> vv(1, 2.0f, 'c'); auto vvv = myget<0>(vv); printf("%d\n", vvv); auto vv2 = myget<2>(vv); printf("%c\n", vv2); getchar(); return 0; }
主要是两个关键,一个是如何构造,一个是get<n>时如何拆分。
如何构造
下面这个mytule会继承另一个模板mytule,并且把模板的参数进行拆分
mytuple<T, Types...> : mytuple<Types...>
假如是tuple<int,float,char>将会继承tuple<float,char>,tuple<float,char>又会继承tuple<char>,因为是继承,所以子类tuple<int,float,char>跟父类是可以转换的。递归的终点是tuple<>。
最终是一个包含的状态
如何拆分
template<size_t n, typename... Types> typename mytuple_element<n, Types...>::type myget(const mytuple<Types...>& tup) { return ((typename mytuple_element<n, Types...>::tuple_type&)tup)._val; }
return的返回值是获取mytuple_element的tuple_type强转成tuple类型。mytuple_element有两个类模板
struct mytuple_element<n, T, Types...> { typedef typename mytuple_element<n - 1, Types...>::type type; typedef typename mytuple_element<n - 1, Types...>::tuple_type tuple_type; }; template <typename T, typename... Types> struct mytuple_element<0, T, Types...> { typedef T type; typedef mytuple<T, Types...> tuple_type; };
这2个模板是递归的,第一个接受参数,一直递归N-1直到参数直到为0最终获取到T的类型。
栗子:定义一个tuple<int,float,char>,调用get<2>(tuple)
第一次
mytuple_element<2,int,Types...(float,char)>=> mytuple_element<1,Types...(float,char)>,int被舍弃
第二次
mytuple_element<1, float ,Types...(char)> => mytuple_element<0, char>,float被舍弃
N至此为0,然后此时mytuple_element<0, char>对应了mytuple_element<0, T, Types...>模板类
最终返回mutuple<char>tuple类型,因为子类可以转化为父类,tuple<int,float,char>转化成mutuple<char>tuple,然后调用mutuple<char>tuple(tuple);最终取得char对应的值。
其实不用get方法,可以通过强转的方式获得指定的值,比如想获得double的值
mytuple<int, double, char> m(10,99.99,'b'); mytuple<double, char> m1 = (mytuple<double, char>)m; std::cout << m1._val;输出99.99。
参考文章:
http://www.newsmth.net/bbstcon.php?board=CPlusPlus&gid=399280
https://blog.csdn.net/libgod/article/details/16980559
http://www.jb51.net/article/70740.htm
https://www.cnblogs.com/flytrace/p/3574647.html