• 《STL源码剖析》traits技法分析


    在完成一个迭代器的时候,我们可能会暴露太多的细节在外面,为了将这些细节给隐藏,我们需要封装,这也是为什么每一种STL容器都提供了一种专属的迭代器。
    为了解决以“迭代器所指对象的型别”为型别
    解决办法是:利用template的参数推导(argument deducation)

    template<class I,class T>
    void func_impl(T iter,T t)
    {
        T temp;//这里解决了问题,T就是所指的对象的型别
    };
    
    template<class I>
    void func(I iter)
    {
     func_impl(iter,*iter);//传入的一个是迭代器,一个是迭代器所指的对象的类型
    }

    这里编译器会自动进行template类型推导,于是可以推导出型别T,顺利解决问题。
    (迭代器相应型别不止是迭代器所指对象的型别一种,最常用的有5种:value_type,difference_type,reference_type,pointer_type,iterator_category)


    为了解决以迭代器所指对象型别为返回值的问题
    在这里我们使用声明内嵌型类型来解决问题:

    template<class T>
    struct MyIter{
    typedef T value_type;//声明内嵌型型别(nested type)
    T*ptr;
    MyIter(T*p=0):ptr(p){}
    T&operator*(){return *ptr}
    };
    
    template<class I>
    typename I::type_value
    func(I ite){
    return *ite;
    }
    
    int main()
    {
    MyIter<int> ite(new int(8));
    cout<<func(ite);//输出结果为8
    }

    但是这种方法有一个隐藏的缺点:无法为原生指针类型制作迭代器,因为内建类型无法定义内部的value_type,所以我们还需要针对特定情况做特定的处理,这时候我们需要特偏化处理(template partial specialization)


    特偏化(template partial specialization)
    (1) 类模板的偏特化
    例如c++标准库中的类vector的定义
    template

    template<class T>
    struct iterator_traits{
    typedef typename T::value_type value_type;
    //这里多加了一层封装,好处是traits可以拥有特化的版本(这里我还是不清楚,为什么说加了封装才能有特化的版本?)
    };
    
    //特化的版本1,为了解决原生指针,比如:int*
    template<class T>
    struct iterator_traits<T*>{
        typename T value_type;//如果是个Int*,可以萃取出int类型
    };
    
    //特化版本2,为了解决原生的const指针,比如:const int*
    template<class T>
    struct iterator_traits<const T*>{
        typename T value_type;//如果是个const int*,可以从中萃取出int类型
    }
    

    这里写图片描述
    最后的效果就像图中这样。

    https://github.com/li-zheng-hao
  • 相关阅读:
    道路和航线
    Sorting It All Out
    Sightseeing Cows(0/1分数规划+Spfa判负环)
    【模板】缩点
    间谍网络
    Tarjan算法专练
    数论知识点总结
    博客迁移到博客园
    第一届CCPC河南省赛
    find程序实现
  • 原文地址:https://www.cnblogs.com/lizhenghao126/p/11053760.html
Copyright © 2020-2023  润新知