2
我正在設計一個網格的容器,表示爲一維數組(模板)。我在這裏發佈代碼的摘錄,其實還有更多。它被用作機器人應用中的滾動佔用網格,其中每個單元代表世界的一個小區域。自定義容器的自定義迭代器
一次操作我與電網經常做的是通過所有的細胞,並取回他們的世界座標:
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迭代器外觀或適配器的文章,但我無法弄清楚如何使其適應我的情況。