在C++中按顺序迭代任意数量的向量

nic*_*ole 2 c++ iterator loops vector chaining

我有一个函数来收集和连接一些向量(当然,使用相同类型的元素).以下是它的简单概念:

vector<A> combined;
...
for(int i = 0; i < someNumber; i++)
    combined.insert(combined.end(), GetNextRange().begin(), GetNextRange().end());
Run Code Online (Sandbox Code Playgroud)

所有这些都完成了,以便我可以按顺序迭代组合集.我希望在没有所有复制业务的情况下实现这一目标.

由于GetNextRange()实际上返回对下一个向量的引用,我如何利用这个事实并将引用放在一起/将它们排成一行以获得所需的访问方法?

Die*_*ühl 5

首先,如果GetNextRange()实际上,确实确实返回了下一个向量,你使用GetNextRange()两次来获得begin()并且end()不会对你有多大帮助.至少你需要做一些事情

for (int i = 0; i != someNumber; ++i) {
    std::vector<A> const& tmp(GetNextRange());
    combined.insert(combined.end(), tmp.begin(), tmp.end());
}
Run Code Online (Sandbox Code Playgroud)

如果你想使这个有点好,你可以创建一个自定义迭代器,它在内部存储当前向量,索引和当前位置.它可能是一个输入迭代器实际上将当前信息存储在合适的共享记录中,因此可以复制它.

这是一个简单的(未经测试的)实现:

class joined_iterator {
    struct record {
        record(int limit)
            : index(0)
            , limit(limit)
            , current(limit? &GetNextRange(): 0)
            , pos()
        {
            if (this->current) {
                this->current->begin();
            }
        }
        int                            index;
        int                            limit;
        std::vector<A> const*          current;
        std::vector<A>::const_iterator pos;
    };
    std::shared_ptr<record> ptr;
public:
    joined_iterator(int limit): ptr(std::make_shared<record>(limit)) {}
    bool operator== (joined_iterator const& other) const {
        return this->ptr->current
            ? bool(other.ptr->current)
            : !bool(other.ptr->current);
    }
    bool operator!= (joined_iterator const& other) const {
        return !(*this == other);
    }
    A const& operator*() const { return *this->ptr->pos; }
    A const* operator->() const { return &*this->ptr->pos; }
    joined_iterator& operator++() {
        if (++this->ptr->pos == this->ptr->current->end()) {
            if (++this->ptr->index == this->ptr->limit) {
                this->ptr->current = 0;
            }
            else {
                this->ptr->current = &GetNextRange();
                this->ptr->pos = this->ptr->current->begin();
            }
        }
        return *this;
    }
    joined_iterator operator++(int) {
        joined_iterator rc(*this);
        this->operator++();
        return rc;
    }
};            
Run Code Online (Sandbox Code Playgroud)