c ++ 11 foreach语法和自定义迭代器

我正在写一个容器的迭代器,用于代替STL容器。 目前,在许多地方使用c ++ 11 foreach语法来使用STL容器,例如: for(auto &x: C) 。 我们需要更新代码以使用包装STL容器的自定义类:

 template< typename Type> class SomeSortedContainer{ std::vector<typename Type> m_data; //we wish to iterate over this //container implementation code }; class SomeSortedContainerIterator{ //iterator code }; 

我如何让自动使用正确的迭代器的自定义容器,以便能够以下面的方式调用代码?

 SomeSortedContainer C; for(auto &x : C){ //do something with x... } 

一般来说,确保auto为类使用正确的迭代器需要什么?

你有两个select:

  • 您提供了名为beginend成员函数,可以称为C.begin()C.end() ;
  • 否则,您可以使用参数相关查找或命名空间std提供名为beginend免费函数,并可以像begin(C)end(C)一样调用。

为了能够使用基于范围的,你的类应该提供const_iterator begin() constconst_iterator end() const成员。 你也可以重载全局begin函数,但是在我看来,有一个成员函数更好。 iterator begin()const_iterator cbegin() const也被推荐,但不是必需的。 如果您只是想遍历一个内部容器,那真的很容易:

 template< typename Type> class SomeSortedContainer{ std::vector<Type> m_data; //we wish to iterate over this //container implementation code public: typedef typename std::vector<Type>::iterator iterator; typedef typename std::vector<Type>::const_iterator const_iterator; iterator begin() {return m_data.begin();} const_iterator begin() const {return m_data.begin();} const_iterator cbegin() const {return m_data.cbegin();} iterator end() {return m_data.end();} const_iterator end() const {return m_data.end();} const_iterator cend() const {return m_data.cend();} }; 

如果你想迭代任何自定义的,你可能必须devise自己的迭代器作为你的容器内的类。

 class const_iterator : public std::iterator<random_access_iterator_tag, Type>{ typename std::vector<Type>::iterator m_data; const_iterator(typename std::vector<Type>::iterator data) :m_data(data) {} public: const_iterator() :m_data() {} const_iterator(const const_iterator& rhs) :m_data(rhs.m_data) {} //const iterator implementation code }; 

有关编写迭代器类的更多详细信息,请参阅我的答案 。

正如其他人所说的,你的容器必须实现begin()end()函数(或者具有以你的容器实例为参数的全局函数或std::函数)。

这些函数必须返回相同的types(通常是container::iterator ,但这只是一个约定)。 返回的types必须实现operator*operator++operator!=

据我所知, SomeSortedContainer只需要提供begin()end() 。 这些应该返回一个标准的顺从迭代器,在你的情况SomeSortedContainerIterator ,它实际上会包装一个std::vector<Type>::iterator 。 对于标准兼容,我的意思是它必须提供通常的增量和取消引用操作符,而且所有的这些value_typereference_type ,… typedefs,这反过来由foreach构造使用,以确定容器元素的基础types。 但你可能只是从std::vector<Type>::iterator转发它们。