"const_iterator"真的需要与"迭代器"是不同的类吗?

Does `const_iterator` really need to be a different class than `iterator`?

本文关键字:quot 是不同 迭代器 const iterator 真的      更新时间:2023-10-16

假设我定义了某种容器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 A::iterator( const StringUtfInterface *p, size_t s); //Not valid

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

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


相关问题(但不相同(:

  • 为什么C++没有常量构造函数?
  • 获取迭代器以供常量参考

const关键字还不够?

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

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

这会阻止您以后使用++it

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

只是重载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); }
//...
};
相关文章: