栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STL源码剖析之萃取(traist)机制

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STL源码剖析之萃取(traist)机制

假设算法依赖于迭代器所指对象的类型,这就需要提取各个迭代器的特性(相应型别)。

对于函数参数及函数内声明局部变量,利用function template的参数推导(argument deducation)机制,相当于重载。

template 
void func_impl(T t, U u) {
    U temp;            // OK, we’ve got the type
                       // The rest work of func…
}
 
template 
void func(T t) {
    func_impl(t, *t); // forward the task to func_impl
}

对于函数返回值,使用内嵌型别声明(nested type),typedef T value_type;但如果不是class type就不能定义内嵌型别,比如原生指针就不是(比如int*)。

template 
struct MyIter {
    typedef T value_type; // A nested type declaration, important!!!
    T* ptr;
    MyIter(T* p = 0) : ptr(p) {}
    T& operator*() const { return *ptr; }
};

template 
typename I::value_type func(I iter) { return *iter; }

Solution: 再加一个间接层,把智能指针和原生指针统统的封装起来。在讨论之前,先要说明一下模板偏特化(template partial specialization)的含义。所谓的偏特化和模板的默认参数是完全不同的两件事情,前者指的是当参数为某一类特定类型的时候,采用特殊的设计,也就是说是“针对template参数更进一步的条件限制所设计出来的一个特化版本”;而默认参数则是当不提供某些参数的时候,使用的一个缺省。

Template  class C {} // 为所有类型为T*的参数而准备的特殊版本

现在来封装“迭代器封装的对象类型”

template 
struct iterator_traits {
    Typedef I::value_type value_type;
}
 
template 
struct iterator_traits {
    typedef T value_type;
};


template
struct iterator_traits {
    typedef T value_type;
}
 
template 
typename iterator_traits::value_type func(I ite) {
    return *ite;
}

萃取技术
有了前面的铺垫,萃取技术就呼之欲出了。不仅是迭代器所指对象的类型,总共萃取以下五种特性(traits)

template 
struct iterator_traits {
    typedef typename I::iterator_category iterator_category;
    typedef typename I::value_type value_type;
    typedef typename I::difference_type difference_type;
    typedef typename I::pointer pointer;
    typedef typename I::reference reference;
}

补充:
迭代器类型

Input Iterator(只读)        Output Iterator(只写)
     |                      |
     +-----------+----------+
                 |
          Forward Iterator
                 |
       Bidirectional Iterator
                 |
       Random Access Iterator

补充:任何一个迭代器的类型永远应该落在该迭代器所属的各种类型中最强的那个(最高阶)。
补充:STL算法中有一个命名规则,以算法所能接受的最低阶迭代器的类型来为其迭代器型别参数命名。
补充:在STL中,所有的迭代器都遵从上面的设计原则,都要提供上面说过的五种类型,但是,人总会有挂一漏万的时候,为了设计上的方便,STL提供了一个标准的迭代器壳

template 
struct iterator {
    typedef Category iterator_category;
    typedef T       value_type;
    typedef Distance difference_type;
    typedef Pointer  pointer;
    typedef Reference reference;
};

这样就免去了声明这些类型的麻烦,当你想自定义一个迭代器的时候只需

template 
struct MyIter : public std::iterator { … }

总结 :萃取利用“内嵌型别”的编程技巧与编译器的template参数推导功能,增强C++不是强类型语言的遗憾。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/657454.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号