为什么STL中没有"Iterable"接口?

sum*_*ier 10 abstract-class iterator design-patterns stl

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;
};
Run Code Online (Sandbox Code Playgroud)

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

vis*_*tor 7

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

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

您正在描述的内容(在值类型上模板化的迭代器)可以使用称为类型擦除的技术(您可以any_iterator在那里找到实现)来实现,就像boost functionany类型一样.

基本思路是:

 //less templated interface
 template <class T>
 class any_iterator_base
 {
     virtual void increment() = 0;
     /*...*/
 };

 //derived class templated on iterator type
 template <class Iter, class T>
 class any_iterator_impl: public any_iterator_base<T>
 {
     Iter it;
     virtual void increment() { ++it; }
     /*...*/
 };

 //and a class for the user which makes it all act like a regular value type
 template <class T>
 class any_iterator
 {
     shared_ptr<any_iterator_base<T> > it;
 public:
     template <class Iter>
     any_iterator(Iter iterator): it(new any_iterator_impl<Iter, T>(iterator)) {}
     any_iterator& operator++() { it->increment(); return *this; }
     //...
 };

 int main()
 {
      std::vector<int> vec;
      any_iterator<int> it = vec.begin();
      //...
 }
Run Code Online (Sandbox Code Playgroud)

它可能比那更复杂(例如,需要做一些关于描述和实施迭代器类别的东西?,如何比较两个any_iterator工作(double dispatch/RTTI?)).