底层集合的抽象迭代器

时间:2012-12-02 15:25:44

标签: c++ c++-standard-library

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

virtual Iterator<T> getIterator() const = 0;

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

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

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

myVector.begin() // compilation error in implementation

使用std::iterator作为类型参数定义const T也没有效果。我还尝试离开T,而是将指针和引用类型定义为const T*const T&

通过查看std::vector实施,我发现std::vector::const_iterator实际上来自_Iterator012来自_Iterator_base

在std中,没有任何方法可以处理任意集合,这真让我感到困惑。 由于两个原因,我不能像<algorithm>那样将我的类实现为模板:

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

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

2 个答案:

答案 0 :(得分:5)

这是使用类型擦除的基本且非常基本的骨架方法。不过,您必须填写 lot 缺少的详细信息!

#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(); }
};

<强>用法:

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

TEIterator<int> a = v.begin(), b = dq.end();

答案 1 :(得分:0)

如果要使用虚方法,则不能使用任意返回值。您可以做的是定义一个基类,它是迭代器的包装器,以及该包装类的子类。

但即便如此,你必须将自己局限于最小的公分母,因为C ++标准库中有几个迭代器类。

因此,AFAICS,如果不使用模板,这种带有任意迭代器的方法实际上是不可行的。