简体   繁体   English

基础集合的抽象迭代器

[英]Abstract iterator for underlying collections

So basically what I want to do is to have a pure virtual method returning an iterator to an arbitrary collection of a concrete type, eg in pseudo code: 因此,基本上我想做的就是拥有一个纯虚拟方法,将一个迭代器返回到一个具体类型的任意集合,例如伪代码:

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

The user of this class actually don't care what implementation the child class uses. 此类的用户实际上并不关心子类使用什么实现。 It could be a set, vector, list, array etc. 它可以是集合,向量,列表,数组等。

I'm aware of the std::iterator class but I cant find a way to specify it correctly in order to work with a simple vector. 我知道std::iterator类,但是我找不到一种可以正确指定它以便使用简单向量的方法。

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

myVector.begin() // compilation error in implementation

defining std::iterator with const T as type parameter hasn't worked too. const T作为类型参数定义std::iterator也不起作用。 I also tried leaving T and instead defining the pointer and reference types as const T* and const T& . 我还尝试离开T ,而是将指针和引用类型定义为const T*const T&

By taking a look at the std::vector implementation, I found out that std::vector::const_iterator actually derives from _Iterator012 deriving from _Iterator_base . 通过查看std::vector实现,我发现std::vector::const_iterator实际上是从_Iterator012派生自_Iterator_base

It really bugs me that there isn't any way to work with arbitrary collections in std. 确实让我感到烦恼的是,没有任何方法可以在std中使用任意集合。 Implementing my classes as templates like in <algorithm> is not an option for me due two reasons: 对我来说,像<algorithm>中那样将类实现为模板不是我的选择,这有两个原因:

  • No control over the actual value type 无法控制实际值类型
  • I simply don't want to make my classes templates complicating my design a lot and making things less flexible. 我只是不想让我的类模板使我的设计复杂得多,并使事情变得不那么灵活。

The used type parameter T was just for demonstration, actually this is a concrete type. 所使用的类型参数T仅用于演示,实际上这是一个具体类型。

Here's a basic and very rudimentary skeleton approach using type erasure. 这是使用类型擦除的基本且非常基本的框架方法。 You'll have to fill in a lot of missing details, though! 不过,您将不得不填写很多遗漏的细节!

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

Usage: 用法:

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

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

If you want to use a virtual method, you cannot use an arbitrary return value. 如果要使用虚拟方法,则不能使用任意返回值。 What you can do, is define a base class, which is a wrapper around iterators, and subclass from that wrapper class. 您可以做的是定义一个基类,它是围绕迭代器的包装器,以及该包装器类的子类。

But even then, you must restrict yourself to the smallest common denominator, since there are several iterator classes in the C++ standard library. 但是即使那样,您也必须限制自己使用最小的公分母,因为C ++标准库中有多个迭代器类。

So, AFAICS, such a method with arbitrary iterators isn't really feasible without using templates. 因此,对于AFAICS,这种带有任意迭代器的方法如果不使用模板就不可行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM