c++ - 使用虚拟派生方法返回不同的迭代器

标签 c++ oop iterator

假设我有一个虚拟基类 Base ,它在某种程度上表现得像一个容器,有两个派生类 VectorLikeRangeLike . 我想实现如下目标:

class VectorLike : public Base {
    std::vector<int> data;
public:
    virtual std::vector<int>::const_iterator cbegin() { return data.cbegin() }
    virtual std::vector<int>::const_iterator cend() { return data.cend() }
}

class RangeLike : public Base {
    int min, max;
    class const_iterator {
        int x;
    public:
        int operator++() { return ++x }
        bool operator==( const_iterator rhs ) { return x == rhs.x }
        const_iterator( int y ) { x = y }
    }
public:
    virtual const_iterator cbegin() { return const_iterator( min ); }
    virtual const_iterator cend() { return const_iterator( max ); }
}

此代码无法编译,因为 std::vector<int>::const_iteratorRangeLike::const_iterator不相同或covariant . 要实现第二个目标,我需要一个迭代器基类,std::vector<int>::const_iterator 都来自该基类。和 RangeLike::const_iterator会得出。但后来还是cbegin()cend()将不得不返回指向迭代器的指针,这将造成更大的困惑。

我的问题是,是否有可能实现类似上述代码的东西,如果可以的话如何实现?

最佳答案

这是一个多态 const int 迭代器的实现。您可以使用任何迭代器类型(包括指针)构造它,其中 std::iterator_traits<Iter>::value_type解析为 int .

std::vector<int> 都应该是这种情况和 your_range_type<int> .

这应该可以帮助您入门。

#include <iostream>
#include <vector>
#include <array>
#include <memory>
#include <algorithm>

struct poly_const_iterator
{
    using value_type = int;

    struct concept {
        virtual void next(int n) = 0;
        virtual const value_type& deref() const = 0;
        virtual bool equal(const void* other) const = 0;
        virtual std::unique_ptr<concept> clone() const = 0;
        virtual const std::type_info& type() const = 0;
        virtual const void* address() const = 0;
        virtual ~concept() = default;
    };

    template<class Iter>
    struct model : concept
    {
        model(Iter iter) : _iter(iter) {}

        void next(int n) override { _iter = std::next(_iter, n); }
        const value_type& deref() const override { return *_iter; }
        bool equal(const void* rp) const override { return _iter == static_cast<const model*>(rp)->_iter; }
        std::unique_ptr<concept> clone() const override { return std::make_unique<model>(*this); }
        const std::type_info& type() const override { return typeid(_iter); }
        const void* address() const override { return this; }


        Iter _iter;
    };

    std::unique_ptr<concept> _impl;

public:
    // interface

    // todo: constrain Iter to be something that iterates value_type
    template<class Iter>
    poly_const_iterator(Iter iter) : _impl(std::make_unique<model<Iter>>(iter)) {};

    poly_const_iterator(const poly_const_iterator& r) : _impl(r._impl->clone()) {};

    const value_type& operator*() const {
        return _impl->deref();
    }

    poly_const_iterator& operator++() {
        _impl->next(1);
        return *this;
    }

    bool operator==(const poly_const_iterator& r) const {
        return _impl->type() == r._impl->type()
        and _impl->equal(r._impl->address());
    }

    bool operator != (const poly_const_iterator& r) const {
        return not(*this == r);
    }
};

void emit(poly_const_iterator from, poly_const_iterator to)
{
    std::copy(from, to, std::ostream_iterator<int>(std::cout, ", "));
    std::cout << std::endl;
}

int main()
{
    std::vector<int> v = { 1, 2, 3, 4, 5 };
    std::array<int, 5> a = { 6, 7,8, 9, 0 };

    emit(std::begin(v), std::end(v));
    emit(std::begin(a), std::end(a));


    return 0;
}

预期结果:

1, 2, 3, 4, 5,
6, 7, 8, 9, 0,

关于c++ - 使用虚拟派生方法返回不同的迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35866041/

相关文章:

c++ - 调用 `list<T>::end()` 不是很低效吗?

c++ - 区分指针和数据变量

c++ - 如果基类指针不能访问派生类成员函数,那多态有什么方便的?

C++ 错误 : A reference of type cannot be initialized with a value of type

c++ - 如何确保迭代器模板参数与模板类的模板参数具有相同的数据类型

javascript - 如何从 Javascript 中的参数访问对象内的对象?

PHP函数列出所有对象的属性和方法

java - 使用堆栈查找二叉搜索树的每个藤蔓的所有节点的非递归方法

c++ - 将 "dumb"函数重构为具有容器迭代器的通用 STL 样式

javascript - 为什么这个函数可以工作但仍然返回 typeError ... is not a function?