我正在设计一个网格容器,表示为一维数组(模板化)。我在这里发布了代码的摘录,实际上还有更多内容。它在机器人应用程序中用作滚动占用网格,其中每个单元代表世界的一小块区域。
我经常对该网格执行的一项操作是遍历所有单元格并检索它们的世界坐标:
for( unsigned r=0; r<mygrid.rows_; ++r ) {
for( unsigned c=0; c<mygrid.cols_; ++c ) {
cell = mygrid.getRC(r,c);
mygrid.rcToXY(r,c,&x,&y);
}
}
我想要一个迭代器来存储所有这些:单元格、它的 rc 坐标和它的 xy 坐标。
for( Grid<CellType>::const_iterator it=mygrid.begin(); it!=mygrid.end(); ++it ) {
cell = *it;
printf("%d %d %f %f\n", it.r(), it.c(), it.x(), it.y());
}
在网上大量的答案和教程之后,我想出了以下实现,它有效。但是对我来说似乎有点笨拙,出于学术考虑,我想让它看起来更好。STL兼容性也很好。
template <class G, typename C>
class base_iterator
{
private:
G* grid_;
C* cell_;
unsigned r_, c_; // local
double x_, y_;
// this should be private with access for friends (Grid) only
// but I can't make it work
public:
base_iterator(G* grid, unsigned r, unsigned c) : grid_(grid), r_(r), c_(c)
{
cell_ = ( r<grid->rows_ && c<grid->cols_ ) ? &grid_->getRC(r,c) : 0;
grid_->rcToXY(r,c,&x_,&y_);
}
public:
base_iterator() : grid_(0) { }
// used to cast an iterator to a const_iterator
template <class G2, typename C2>
base_iterator(const base_iterator<G2,C2>& other)
{
grid_ = other.grid();
cell_ = & other.cell();
r_ = other.r();
c_ = other.c();
x_ = other.x();
y_ = other.y();
}
// this should be private with access for friends only
G* grid() const { return grid_; }
C& cell() { return *cell_; }
const C& cell() const { return *cell_; }
unsigned r() const { return r_; }
unsigned c() const { return c_; }
double x() const { return x_; }
double y() const { return y_; }
C* operator->() { return cell_; }
const C* operator->() const { return cell_; }
C& operator*() { return *cell_; }
const C& operator*() const { return *cell_; }
//prefix
base_iterator & operator++()
{
// my iteration logic here which needs access to grid
// in order to find the number of rows, etc.
return *this;
}
//postfix
base_iterator operator++(int)
{
base_iterator it(*this); // make a copy for result
++(*this); // Now use the prefix version to do the work
return it; // return the copy (the old) value.
}
template <class G2, typename C2>
bool operator==(const base_iterator<G2,C2> & other) const
{
return cell_ == &other.cell();
}
template <class G2, typename C2>
bool operator!=(const base_iterator<G2,C2>& other) const
{ return cell_!=other.cell(); }
};
然后在我的网格类中:
typedef base_iterator<Grid<T>,T> iterator;
typedef base_iterator<Grid<T> const, T const> const_iterator;
iterator begin() { return iterator(this,0,0); }
iterator end() { return iterator(this,rows_,cols_); }
const_iterator begin() const { return const_iterator(this,0,0); }
const_iterator end() const { return const_iterator(this,rows_,cols_); }
同样,这可行,但我觉得它有点笨拙(参见迭代器代码中的注释),我想知道如何改进它。我看到很多关于使用 boost 迭代器外观或适配器的帖子,但我不知道如何使其适应我的情况。