`const_iterator`真的需要与`iterator`不同吗?

时间:2017-07-03 09:43:39

标签: c++ constructor iterator const const-iterator

假设我定义了某种容器A

struct A
{
    iterator begin(){ return iterator(this,0); }
    const iterator cbegin() const { return iterator(this, last());}
    //...
};

现在假设我要声明iterator(A的一部分):

struct A::iterator
{
    iterator ( A* ptr, size_t idx){};
    //...
};

我会用的是:

const A a;
A::iterator it = a.cbegin();

这不起作用,因为传递给iterator的构造函数的指针是非const的。

理想的解决方案就像返回const对象的特定构造函数:

const A::iterator( const StringUtfInterface *p, size_t s); //Not valid

这显然在C ++中无效。我想知道这个问题的解决方法是什么?

我真的需要声明/定义一个新的const_iterator类吗? const关键字还不够?

相关问题(但不一样):

2 个答案:

答案 0 :(得分:3)

  

const关键字还不够?

实际上,const关键字太多了:它迫使你写

const A::iterator it = a.cbegin();

阻止您稍后使用++it

您需要提供两个单独的类,但这并不意味着您必须编写两次代码。您可以构造迭代器的实现,使得执行所有工作的公共类嵌入在常量和非常量迭代器实现中,这将实现嵌入式实现的相关方法给调用者。

答案 1 :(得分:1)

如果仅重载iterator的构造函数以支持常量容器呢?

struct A::iterator {
    iterator(A* ptr, size_t idx) {}
    iterator(const A* ptr, size_t idx) {}
    //...
};

通过这种方式,没有必要定义两个单独的类,并且您将始终根据容器常量获取(隐式)正确的迭代器。

<强>更新

发表评论后,您可以使用模板,例如(非完整实施)

struct A {
  template<class T>
  struct base_iterator {
  private:
    T* _ptr;

  public:
    base_iterator(T* ptr, size_t idx) : _ptr(ptr) {}

    T operator*() { return *_ptr; }
    //...
  };

  typedef base_iterator<A> iterator;
  typedef base_iterator<const A> const_iterator;

  iterator begin() { return iterator(this, 0); }
  const_iterator cbegin() const { return const_iterator(this, 0); }
  //...
};