为什么STL中没有“Iterable”接口?

时间:2010-10-18 12:12:59

标签: design-patterns stl iterator abstract-class

C ++ STL似乎不经常使用纯粹的抽象基类(也就是接口)。我知道大多数事情都可以通过STL算法或聪明的模板元编程来实现。

但是,对于某些用例(例如,在API中,如果我不想具体说明我获得的容器类型,只是它包含的元素),则以下形式的接口将是很好:

template<typename T> struct forward_iterable {
    struct iterator {
        typedef T  value_type;
        typedef T& reference;
        typedef T* pointer;
        virtual reference operator*() const = 0;
        virtual pointer operator->() const = 0;
        virtual bool operator==(const iterator&) const = 0;
        virtual bool operator!=(const iterator&) const = 0;
        virtual operator const_iterator() const = 0;
        virtual iterator& operator++() = 0;
        virtual iterator  operator++(int) = 0;
    };
    struct const_iterator { ... };  // similar, but with const references

    virtual iterator begin() = 0;
    virtual const_iterator begin() const = 0;
    virtual iterator end() = 0;
    virtual const_iterator end() const = 0;
};

如果STL容器将此类实现为非虚函数,我认为这不会影响性能(如果我直接使用容器而不是通过此接口)。那么为什么STL中的“接口”如此之少呢?或者我只是用“Java”术语思考太多了?

3 个答案:

答案 0 :(得分:6)

STL(它是标准库的一个子集)根本不使用OOP(如在运行时多态性中),这是设计使然。

根据您的设计,按值返回迭代器是否存在问题(协方差对值类型不起作用)?也就是说,整个事件不可避免地要依赖静态成员(可以通过引用返回)还是依赖于堆分配的迭代器?后者在非垃圾收集语言中看起来相当尴尬。

你所描述的(在值类型上模板化的迭代器)可以使用一种名为type-erasure的技术来实现(你可以在那里找到any_iterator实现)就像boost function和{{ 1}}类型。

基本理念是:

any

它可能比那更复杂(例如需要对描述和实施迭代器类别做些什么?,如何比较两个any_iterators工作(double dispatch / RTTI?))。

答案 1 :(得分:2)

你在STL中没有看到很多“接口”式抽象基类的原因是因为它在很大程度上依赖于C ++模板。当你使用C ++模板时,几乎任何类,无论它的父级是什么,只要它支持模板试图使用的所有方法,它都会做。

有一种隐含的界面,但实际上写出来是无关紧要的。在我自己的编码中,我倾向于写一个,只是为了方便用户,但这不是STL作者如何滚动。

答案 2 :(得分:0)

STL结构未定义继承。为子类化任何stl集合做一个好的案例并不容易。考虑到这一点,stl不会让你“支付”可能与正常类继承相关的任何费用。如果要使用虚拟方法,则优化程序无法对它们进行内联。

此外,STL希望与那些无法从顶级抽象基类继承的东西兼容,比如数组。