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
c++11 foreach syntax and custom iterator
提问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
begin
andend
that can be called likeC.begin()
andC.end()
; - otherwise, you provide free functions named
begin
andend
that can be found using argument-dependent lookup, or in namespacestd
, and can be called likebegin(C)
andend(C)
.
- 您提供命名的成员函数
begin
,end
并且可以像C.begin()
and一样调用C.end()
; - 否则,您可以提供名为
begin
and 的免费函数,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() const
and const_iterator end() const
members. You can also overload the global begin
function, but having a member function is better in my opinion. iterator begin()
and const_iterator cbegin() const
are also recommended, but not required. If you simply want to iterate over a single internal container, that's REALLY easy:
为了能够使用基于范围的 for,您的类应该提供const_iterator begin() const
和const_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 SomeSortedContainer
just 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
.