底层集合的抽象迭代器

Seb*_*ann 5 c++ c++-standard-library

基本上我想做的是让一个纯虚方法将迭代器返回到具体类型的任意集合,例如伪代码:

virtual Iterator<T> getIterator() const = 0;
Run Code Online (Sandbox Code Playgroud)

该类的用户实际上并不关心子类使用的实现.它可以是一个集合,向量,列表,数组等.

我知道这个std::iterator类,但我无法找到一种方法来正确指定它以便使用一个简单的向量.

virtual std::iterator<std::random_access_iterator_tag,T> getIterator() const = 0;

myVector.begin() // compilation error in implementation
Run Code Online (Sandbox Code Playgroud)

std::iteratorconst Tas作为类型参数定义也没有用.我也尝试离开T,而是将指针和引用类型定义为const T*const T&.

通过查看std::vector实现,我发现std::vector::const_iterator实际上源于_Iterator012派生_Iterator_base.

真的让我感到困惑的是,在std中没有任何方法可以处理任意集合.<algorithm>由于两个原因,将我的类作为模板实现,对我来说不是一个选择:

  • 无法控制实际值类型
  • 我根本不想让我的类模板使我的设计复杂化并使事情变得不那么灵活.

使用的类型参数T仅用于演示,实际上这是一种具体类型.

Ker*_* SB 5

这是使用类型擦除的基本且非常基本的骨架方法.但是,你必须填写很多遗漏的细节!

#include <memory>

template <typename T>
class TEIterator
{
    struct TEImplBase
    {
        virtual ~TEImplBase() { }
        virtual std::unique_ptr<TEImplBase> clone() const = 0;
        virtual void increment() = 0;
        virtual T & getValue() = 0;
        T * getPointer() { return std::addressof(getValue()); }
    };

    template <typename Iter>
    struct TEImpl
    {
        Iter iter;

        TEImpl(Iter i) : iter(i) { }

        virtual T & getValue()
        { return *iter; }

        virtual std::unique_ptr<TEImplBase> clone() const
        { return std::unique_ptr<TEImplBase>(new TEImpl<Iter>(*this)); }

        virtual void increment()
        { ++iter; }
    };

    std::unique_ptr<TEImplBase> impl;

public:

    template <typename T>
    TEClass(T && x)
    : impl(new TEImpl<typename std::decay<T>::type>(std::forward<T>(x)))
    {
    }

    TEClass(TEClass && rhs) = default;

    TEClass(TEClass const & rhs) : impl(rhs.impl.clone()) { }

    TEIterator & operator++()
    {
        impl->increment();
        return *this;
    }

    T & operator*() { return impl->getValue(); }
    T * operator->() { return impl->getPointer(); }
};
Run Code Online (Sandbox Code Playgroud)

用法:

std::vector<int> v;
std::deque<int> dq;

TEIterator<int> a = v.begin(), b = dq.end();
Run Code Online (Sandbox Code Playgroud)