简体   繁体   English

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

[英]c++11 foreach syntax and custom iterator

I am writing an iterator for a container which is being used in place of a STL container. 我正在编写一个用于代替STL容器的容器的迭代器。 Currently the STL container is being used in many places with the c++11 foreach syntax eg: for(auto &x: C) . 目前,STL容器正在许多地方使用c ++ 11 foreach语法,例如: for(auto &x: C) We have needed to update the code to use a custom class that wraps the STL container: 我们需要更新代码以使用包装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
};

How do I get auto to use the correct iterator for the custom container so the code is able to be called in the following way?: 如何让自动为自定义容器使用正确的迭代器,以便能够以下列方式调用代码?:

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

In general what is required to ensure that auto uses the correct iterator for a class? 一般来说,确保auto为类使用正确的迭代器需要什么?

To be able to use range-based for, your class should provide const_iterator begin() const and const_iterator end() const members. 为了能够使用基于范围的for,您的类应该提供const_iterator begin() constconst_iterator end() const成员。 You can also overload the global begin function, but having a member function is better in my opinion. 你也可以重载全局begin函数,但在我看来,拥有成员函数更好。 iterator begin() and const_iterator cbegin() const are also recommended, but not required. 也建议使用iterator begin()const_iterator cbegin() const ,但不是必需的。 If you simply want to iterate over a single internal container, that's REALLY easy: 如果您只是想迭代一个内部容器,那真的很容易:

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();}
};    

If you want to iterate over anything custom though, you'll probably have to design your own iterators as classes inside your container. 如果你想迭代任何自定义,你可能必须将自己的迭代器设计为容器内的类。

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
};

For more details on writing an iterator class, see my answer here . 有关编写迭代器类的更多详细信息,请参阅此处的答案

You have two choices: 你有两个选择:

  • you provide member functions named begin and end that can be called like C.begin() and C.end() ; 你提供名为beginend成员函数,可以像C.begin()C.end()一样C.begin() ;
  • otherwise, you provide free functions named begin and end that can be found using argument-dependent lookup, or in namespace std , and can be called like begin(C) and end(C) . 否则,您提供名为beginend自由函数,可以使用参数依赖查找或命名空间std查找,并且可以像begin(C)end(C)一样调用。

As others have stated, your container must implement begin() and end() functions (or have global or std:: functions that take instances of your container as parameters). 正如其他人所说,您的容器必须实现begin()end()函数(或者具有将容器实例作为参数的全局或std::函数)。

Those functions must return the same type (usually container::iterator , but that is only a convention). 这些函数必须返回相同的类型(通常是container::iterator ,但这只是一个约定)。 The returned type must implement operator* , operator++ , and operator!= . 返回的类型必须实现operator*operator++operator!=

To my knowledge SomeSortedContainer just needs to provide begin() and end() . 据我所知, SomeSortedContainer只需要提供begin()end() And these should return a standard compliant forward iterator, in your case SomeSortedContainerIterator , which would actually wrap a std::vector<Type>::iterator . 这些应该返回一个标准的兼容前向迭代器,在你的情况下SomeSortedContainerIterator ,它实际上会包装一个std::vector<Type>::iterator With standard compliant I mean it has to provide the usual increment and dereferencing operators, but also all those value_type , reference_type , ... typedefs, which in turn are used by the foreach construct to determine the underlying type of the container elements. 标准兼容我的意思是它必须提供通常的增量和解引用运算符,还有所有那些value_typereference_type ,... typedef,而foreach结构又使用它来确定容器元素的基础类型。 But you might just forward them from the std::vector<Type>::iterator . 但是你可能只是从std::vector<Type>::iterator转发它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM