想象一下,有一个具有一些特定属性的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。
答案 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;
}