关于tuple的一些小总结
c11新增了tuple,之前在写脚本时候,也感受这个的强大,一直没有时间去弄明白在c++实现的话应该怎么做。
最近刚好有时间去看下c11的一些特性,发现已经加上了,赶紧去看看里面的一个原理。
简单来说运用了模板的特性,一个是特化优先于模板。先看看存取的类
// 1. primary 模板(可变模板 - 使用 pack parameter) template <typename... Ts> struct MyTuple; // 2. 显式特化:空 tuple template <> struct MyTuple<> {}; // 3. 部分特化:递归定义(重点!) template <typename This, typename... Rest> struct MyTuple<This, Rest...> : MyTuple<Rest...> { This value; // 存储的值 // 调用基类的构造函数以初始化基类子对象,再初始化 value MyTuple(This f, Rest... rest): MyTuple<Rest...>(forward<Rest>(rest)...), value(f) {} }; MyTuple t(1, 'a', "hello");
这里就引用别人的代码了,这里就是利用特化的来实现递归,从而存了数据。
数据存了是第一步,第二步是找回它,所以你会看到std::get,它实现也是跟存类似,只是多了个index
// primary 模板 template <int Index, typename Tuple> struct MyTupleElement; // 部分特化:第0个元素的类型就是 This,t要转换的目标类型就是原始类型(即不需要转换) template <typename This, typename... Rest> struct MyTupleElement < 0, MyTuple<This, Rest...>> { using elementType = This; using tupleType = MyTuple<This, Rest...>; }; // 部分特化:递归定义(重点!) template <int Index, typename This, typename... Rest> struct MyTupleElement<Index, MyTuple<This, Rest...>> : MyTupleElement<Index-1, MyTuple<Rest...>> {}; template <int Index, typename... Ts> typename MyTupleElement<Index, MyTuple<Ts...>>::elementType myGet(MyTuple<Ts...>& t) { using tupleType = typename MyTupleElement<Index, MyTuple<Ts...>>::tupleType; return static_cast<tupleType&>(t).value; }
这里用myGet去实现一个index,类似于一个static_cast从而找到该index。
这里想一个问题,如果当纯的index,模板会在实例化才生成,如果转指针呢?是否会生成
template<int index> struct testTemplate{ void say() { cout << index <<endl; } }; testTemplate<23> rer; reinterpret_cast<testTemplate<25>* >(&rer)->say(); rer.say();
这里的reinterpret_cast<testTemplate<25>* >(&rer)->say()是否会崩溃?跑了一下是不会的
template<typename index> struct testTemplate{ index test; testTemplate(index fd): test(fd) {} void say() { index fdsf = static_cast<index>(test); cout << &test<< " " << fdsf<<endl; } }; int main() { testTemplate<double> rer(43.5); reinterpret_cast<testTemplate<int>* >(&rer)->say(); rer.say(); int testfff = static_cast<int> (rer.test); cout << &rer.test<<" " << testfff <<endl; }
这里输出反而是
0x7ffdd042bf88 0
0x7ffdd042bf88 43.5
0x7ffdd042bf88 43
原因是double 64位。。。。相当于强制那块内存,从汇编上看,也生成一个类
浙公网安备 33010602011771号