关于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位。。。。相当于强制那块内存,从汇编上看,也生成一个类

posted @ 2020-10-13 17:23  ouyang_hang  阅读(143)  评论(0)    收藏  举报