【发布时间】:2011-05-03 03:06:11
【问题描述】:
我正在为我的科学软件实现一个带有类似 STL 接口的自定义容器,用于 3D 网格控件。这是我关于这个容器的迭代器类的第二个问题。感谢您通过the first 帮助我!
我的问题就像"How do you avoid code duplication when implementing const and non-const iterators?"。我只是想问是否可以提供无模板解决方案? (并且没有提供第二个 const 迭代器类!)
迭代器类如下所示:
class spGridIterator {
public:
typedef forward_iterator_tag iterator_category;
typedef spGridNode value_type;
typedef int difference_type;
typedef spGridNode* pointer;
typedef spGridNode& reference;
spGridIterator();
spGridIterator(spGrid* gr, int index);
spGridIterator(const spGridIterator& orig);
virtual ~spGridIterator();
// STL-ные операторы итератора
bool operator == ( const spGridIterator& hs ) const {
return (m_grid == hs.m_grid) && (m_idx == hs.m_idx);
}
bool operator != ( const spGridIterator& hs ) const {
return (m_grid != hs.m_grid) || (m_idx != hs.m_idx);
}
// non-const operators
spGridIterator& operator++();
spGridIterator& operator++(int);
reference operator*() const;
pointer operator->() const { return &(operator*()); }
private:
spGrid* m_grid;
int m_idx;
};
还有一个实现...
spGridIterator::spGridIterator(spGrid* gr, int index) {
m_grid = gr;
m_idx = index;
}
spGridIterator& spGridIterator::operator++()
{
int last = m_grid->numpoints;
if (m_idx < last) {
m_idx++;
}
return *this;
}
spGridIterator& spGridIterator::operator++(int) {
return operator++();
}
spGridIterator::reference spGridIterator::operator*() const {
return ( m_grid->GetNode(m_idx) );
}
我检查了doctor dobbs article 关于自定义迭代器实现的信息。他们建议实现一个迭代器类模板并为value_type 添加一个额外的模板参数。
嗯,第二种解决方案是提供一个常规迭代器和一个 const 迭代器类。
是否有第三种,可能是“有点老套”的单类无模板解决方案?也许提供一个转换运算符或operator++() 的附加 const 版本?
谢谢, 伊利亚
【问题讨论】:
-
你的
operator++(int)返回错误的值 - 它是后缀++,所以它应该返回迭代器的副本之前被递增,而不是对迭代器的引用在被迭代之后。规范实现是Iterator Iterator::operator++(int) { Iterator old = *this; ++(*this); return old; } -
我明白了!感谢您的宝贵意见!
-
我真的不需要我不会实现后缀 ++ 运算符。您真的想鼓励人们使用前缀 ++ 运算符而不是后缀 ++ 运算符。
-
@Patrick:好主意,但如果它没有后缀 ++,那么根据标准,它就不是迭代器。