【问题标题】:One single class for const and non-const iterators. Is it possible?一个用于 const 和非 const 迭代器的类。可能吗?
【发布时间】: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:好主意,但如果它没有后缀 ++,那么根据标准,它就不是迭代器。

标签: c++ stl iterator


【解决方案1】:

如果你想搞点hacky,你可以滥用“const_cast”从非常量迭代器中创建一个const迭代器。

【讨论】:

  • 简单的技巧,但它有效。不要忘记在源代码中明确说明您滥用 const_cast 的原因。否则,下一个阅读代码的开发人员会认为你犯了一个错误,并且会想要纠正你的错误,呃,诡计。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 2012-01-28
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多