为啥列表迭代器在 SGI STLs 实现中具有三个模板参数?

Posted

技术标签:

【中文标题】为啥列表迭代器在 SGI STLs 实现中具有三个模板参数?【英文标题】:Why list iterator has three template arguments in SGI STL's implemention?为什么列表迭代器在 SGI STLs 实现中具有三个模板参数? 【发布时间】:2018-06-29 11:29:16 【问题描述】:

我在阅读 SGI STL 的列表迭代器实现时遇到问题。

template<class T>
struct __list_node 
    void *prev;
    void *next;
    T data;
;

template<class T, class Ref, class Ptr>
struct __list_iterator 
    typedef __list_iterator<T, T&, T*> iterator;
    typedef __list_iterator<T, Ref, Ptr> self;
    ...
    typedef T value_type;
    typedef Ptr pointer;
    typedef Ref reference;
    typedef __list_node<T>* link_type;
    ...
    link_type node;
    ...
    reference operator*() const  return (*node).data; 
    pointer operator-> const  return &(operator*()); 
    self& operator++()  ... 
    self operator++(int)  ... 
    ...
    ...
;

那么,为什么会有三个模板参数? 如果只有class T 存在怎么办?喜欢下面的东西。

template<class T>
struct __list_iterator 
    typedef __list_iterator<T> iterator;
    typedef __list_iterator<T> self;
    ...
    typedef T value_type;
    typedef T* pointer;
    typedef T& reference;
    ...
    ...
;

我想知道对于某些特定的class T 或某些我无法弄清楚的原因,三个参数是否是必须的。 希望有人可以帮助我。非常感谢!

【问题讨论】:

这些是用户不应该感兴趣的实现细节(名称前的两个下划线是一个很大的提示)。用户只需使用std::list&lt;TheirType&gt;::iterator。这可以定义为具有三个或五个或十七个参数的模板的实例化,无论今天的实现是否方便。 在过去,使用分段内存,我们有不同类型的指针:What are near, far, and huge pointers? STL 的早期预标准版本设想Allocator::pointer 可能不是Allocator::value_type*,而Allocator::reference 可能不是Allocator::value_type&amp;。容器应该处理这种情况。到了 C++98,这个想法已经被抛弃了,Allocator::pointer 需要是一个真正的指针。也许您研究的实现可以追溯到过去。 【参考方案1】:

Alexander Stepanov(STL 的发明者)解释了为什么在他的课程使用组件进行高效编程期间,Lecture 11 在 STL 中引入了 referencepointer 成员别名。

简而言之,Stepanov 最初认为 – 给定一个迭代器 it*it 可以安全地假定为 value_type&amp; 类型,并且 &amp;*itvalue_type* 类型。然而,微软表示它将投票反对将 STL 包含在标准中,除非它可以容纳多种内存模型,当时包括具有微小、巨大和长指针的模型。因此,引入referencepointer。从讲座中引用他的话:

“这并不是特别有害,但它会混淆事物。它当然受到语言专家的喜爱;它为他们提供了稳定的就业机会。”

有趣的是,即使 Stepanov 改变了 STL 的整个架构以试图满足其要求,微软仍然决定投票反对包含。

类的相关部分是here。

【讨论】:

以上是关于为啥列表迭代器在 SGI STLs 实现中具有三个模板参数?的主要内容,如果未能解决你的问题,请参考以下文章

Lua 迭代器

SGI STL源码stl_bvector.h分析

SGI-STL简记-构造类型萃取特性未初始化解析

为啥迭代器指向的数据在从列表中删除后保留

SGI-STL简记-迭代器解析

迭代器在spark中的应用