5

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

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::iteratorconst T类型参数也没有奏效。我还尝试离开T,而是将指针和引用类型定义为const T*and const T&

通过查看实现,std::vector我发现它std::vector::const_iterator实际上源自_Iterator012._Iterator_base

没有任何方法可以处理 std 中的任意集合,这真的让我很困扰。由于两个原因,将我的类实现为模板<algorithm>对我来说不是一个选项:

  • 无法控制实际值类型
  • 我只是不想让我的类模板使我的设计复杂化很多并且让事情变得不那么灵活。

使用的类型参数T只是为了演示,实际上这是一个具体的类型。

4

2 回答 2

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

用法:

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

TEIterator<int> a = v.begin(), b = dq.end();
于 2012-12-02T15:51:55.577 回答
0

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

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

所以,AFAICS,这种带有任意迭代器的方法在不使用模板的情况下是不可行的。

于 2012-12-02T15:46:20.033 回答