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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7562356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:08:36  来源:igfitidea点击:

c++11 foreach syntax and custom iterator

c++iteratorc++11

提问by shuttle87

I am writing an iterator for a container which is being used in place of a STL container. Currently the STL container is being used in many places with the c++11 foreach syntaxeg: for(auto &x: C). We have needed to update the code to use a custom class that wraps the STL container:

我正在为一个用于代替 STL 容器的容器编写迭代器。目前,STL 容器在许多地方使用c++11 foreach 语法,例如: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
};

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?:

如何让 auto 为自定义容器使用正确的迭代器,以便能够通过以下方式调用代码?:

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 为类使用正确的迭代器?

采纳答案by R. Martinho Fernandes

You have two choices:

你有两个选择:

  • you provide member functions named beginand endthat can be called like C.begin()and C.end();
  • otherwise, you provide free functions named beginand endthat can be found using argument-dependent lookup, or in namespace std, and can be called like begin(C)and end(C).
  • 您提供命名的成员函数beginend并且可以像C.begin()and一样调用C.end()
  • 否则,您可以提供名为beginand 的免费函数,end这些函数可以使用依赖于参数的查找或在 namespace 中找到std,并且可以像begin(C)and一样调用end(C)

回答by Mooing Duck

To be able to use range-based for, your class should provide const_iterator begin() constand const_iterator end() constmembers. You can also overload the global beginfunction, but having a member function is better in my opinion. iterator begin()and const_iterator cbegin() constare also recommended, but not required. If you simply want to iterate over a single internal container, that's REALLY easy:

为了能够使用基于范围的 for,您的类应该提供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();}
};    

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.

有关编写迭代器类的更多详细信息,请在此处查看我的回答

回答by dspeyer

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). The returned type must implement operator*, operator++, and operator!=.

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

回答by Christian Rau

To my knowledge SomeSortedContainerjust needs to provide begin()and end(). And these should return a standard compliant forward iterator, in your case SomeSortedContainerIterator, which would actually wrap a 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. But you might just forward them from the std::vector<Type>::iterator.

据我所知,SomeSortedContainer只需要提供begin()end()。这些应该返回一个标准兼容的前向迭代器,在你的情况下SomeSortedContainerIterator,它实际上会包装一个std::vector<Type>::iterator. 与标准兼容我的意思是它必须提供通常的增量和取消引用运算符,但也提供所有那些value_type, reference_type, ... typedef,foreach 构造依次使用它们来确定容器元素的基础类型。但是您可能只是将它们从std::vector<Type>::iterator.