我正在为我的科学软件编写一个3D网格,我需要遍历网格的节点来获取它们的坐标。而不是将每个节点对象保存在容器中,我宁愿只是在迭代时动态计算坐标。问题是stl :: iterator需要返回operator*()
或operator->()
指针引用的值。
下面的一些代码:
class spGridIterator {
public:
typedef forward_iterator_tag iterator_category;
typedef spVector3D value_type;
typedef int difference_type;
typedef spVector3D* pointer;
typedef spVector3D& reference;
spGridIterator(spGrid* gr, int index);
spGridIterator& operator++();
spGridIterator& operator++(int);
reference operator*() const;
pointer operator->() const;
private:
spGrid* m_grid;
int m_idx;
};
spGridIterator::reference spGridIterator::operator*() const {
// return m_grid->GetPoint(m_idx);
}
spGridIterator::pointer spGridIterator::operator->() const {
// return m_grid->GetPoint(m_idx);
}
此方法按提供的索引查询节点坐标
spVector3D spGrid::GetPoint(int idx) const {
// spVector3D vec = ... calculate the coordinates here ...
return vec;
}
关于此的任何输入?
提前致谢, 伊利亚安德
答案 0 :(得分:6)
您可以使用成员变量来保存当前指向的网格点:
class spGridIterator {
public:
typedef forward_iterator_tag iterator_category;
typedef spVector3D value_type;
typedef int difference_type;
typedef spVector3D* pointer;
typedef const spVector3D* const_pointer;
typedef const spVector3D& const_reference;
typedef spVector3D& reference;
spGridIterator(spGrid* gr, int index);
spGridIterator& operator++();
spGridIterator& operator++(int);
reference operator*();
const_reference operator*() const;
pointer operator->();
const_pointer operator->() const;
private:
spGrid* m_grid;
int m_idx;
mutable spVector3D CurrentPoint;
};
然后解引用运算符可能如下所示:
spGridIterator::const_reference spGridIterator::operator*() const {
CurrentPoint = m_grid->GetPoint(m_idx);
return CurrentPoint;
}
感谢@greg指出CurrentPoint
需要mutable
才能生效。这将是一个惰性实现(仅在迭代器实际解除引用时检索点)。急切的实现会更新迭代器的mutator方法中的CurrentPoint
成员(本例中为operator++
变体),使mutable
变得多余。
答案 1 :(得分:1)
由于迭代器是一个值对象,为什么不将成员设置为要返回的值,并返回对该成员的引用?
答案 2 :(得分:1)
简短的回答是,这会导致未定义的行为,你毕竟返回一个临时的引用!一个选项(如果这个迭代器不需要重入)是有一个类成员(类型为spVector3D),你可以“分配”返回的值(当然你可以通过传入对此的引用来更好地完成它) GetPoint以及索引),然后返回。
答案 3 :(得分:1)
我知道这篇文章太旧了,只是因为我有同样的问题" 和谷歌把我带到这里,我将加上我的两分钱,这是我发现的:
至少在C ++库中有许多迭代器类型,每个类型声明一些相关的语义。类型是
在您的问题情况下,输入迭代器语义适合。特别是在输入迭代器operator*()
中,它不必返回对象的引用,它甚至可以返回一个新创建的对象。因此,避免使用"虚拟"在Bjorn建议的迭代器对象里面的对象。
您可以查看更多here。