迭代多个嵌套向量

时间:2015-10-05 07:12:19

标签: c++ vector stl iterator c++98

想象一下,有一个具有一些特定属性的A类向量。其中,它具有类型B的向量。此外,B具有类型向量的成员变量。迭代所有给定C的最佳方法是什么?

天真的方式是使用嵌套循环。将类型C的对象的属性foo更改为类似

的类型
for (i=0; i<as.size(); i++)
  for (j=0; j<as[i].bs.size(); j++)
    for (k=0; k< as[i].bs[j].cs.size(); k++)
      as[i].bs[j].cs[k].foo = bar

如果我必须经常以这种方式迭代C类的所有对象;也许有一个更复杂的身体;代码变得相当混乱。除了附加的标识之外,这些嵌套的for循环结构通过代码重复。

有更优雅的方法吗?我可以为我声明某种迭代器吗?我被迫使用C ++ 98。

1 个答案:

答案 0 :(得分:1)

  • 你可以做一个功能:

    template <typename T, typename F>
    void my_for_each(std::vector<std::vector<std::vector<T>>>& v, F f)
    {
        for (std::size_t i = 0; i != as.size(); i++)
            for (std::size_t j = 0; j != as[i].bs.size(); j++)
                for (std::size_t k = 0; k != as[i].bs[j].cs.size(); k++)
                    f(as[i].bs[j].cs[k].foo);
                }
            }
        }
    }
    

    这需要仿函数使用它:

    struct bar_assigner
    {
        bar_assigner(int bar) : bar(bar) {}
    
        operator () (int& e) const { e = bar; }
    
        int bar;
    }
    

    并像

    一样使用它
    my_for_each(as, bar_assigner(bar));
    
  • 另一种方法是展平你的数组(如果每个内部向量具有相同的大小):

    class Matrix3
    {
        public:
            typedef std::vector<int>::iterator iterator;
    
            Matrix3(std::size_t a_size, std::size_t b_size, std::::size_t c_size) :
            a_size(a_size), b_size(b_size), c_size(c_size), v(a_size * b_size * c_size){}
    
            int& operator()(std::size_t i, std::size_t j, std::size_t k)
            { return b_size * c_size * i + c_size * j + k; }
    
            iterator begin() { return v.begin(); }
            iterator end() { return v.end(); }
    
            // ...
    
        private:
            std::size_t a_size;
            std::size_t b_size;
            std::size_t c_size;
            std::vector<int> v;
    };
    

    用法:

    for (Matrix3::iterator it = m.begin(); it != m.end(); ++it) {
        *it = bar;
    }
    
  • 第三种方法是创建自己的迭代器:

    class Iterator3D
    {
    public:
        Iterator3D& operator ++() {/*..*/}
        int& operator *() {/*..*/}
        int* operator ->() { return &this->operator *(); }
        operator ==(const Iterator3D& rhs) const {/*..*/}
    
    private:
        std::vector<std::vector<std::vector<int>>>& v;
        std::size_t index_a;
        std::size_t index_b;
        std::size_t index_c;
    };
    

    用法:

    for (Iterator3D it = my_begin(as); it != as_end(as); ++it) {
        *it = bar;
    }