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

时间:2013-12-09 22:40:01

标签: c++ loops vector iterator chaining

我有一个函数可以收集和连接一些向量(当然,使用相同类型的元素)。以下是它的基本想法:

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

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

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

2 个答案:

答案 0 :(得分: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());
}

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

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

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

答案 1 :(得分:0)

我想按顺序迭代两个向量,并认为必须有一个更简单的答案。我的以下解决方案(C++11 实现,但很容易适应旧版本) - 在我最初忽略的 Dietmar Kühls 答案的评论中暗示,我最初忽略了它们 - 不是那么复杂,但对我的用例起到了作用:

vector<vector<A>*> v_ps;
for ( int i = 0; i != someNumber; ++i ) {
    v_ps.push_back( &GetNextRange() );
}
for( auto v_p : v_ps ){
    for( A& el : *v_p ){
        // do what you wish with el
    }
}

注意:我假设 GetNextRange() 返回下一个要迭代的向量

注二:由于它没有那么复杂,它有缺点,特别是需要一直使用双 for 循环。如果可以接受,这取决于您和您的申请。

注意三:我保留了对单个元素进行更改的可能性