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