[英]From integer-indexed for loop enumeration to range-for
I have some code that enumerates some data, something like this: 我有一些代码列举了一些数据,如下所示:
int count;
InitDataEnumeration(/* some init params */, &count);
for (int i = 0; i < count; i++)
{
EnumGetData(i, &data);
// process data ...
}
I'd like to convert this code in a form suitable to C++11's range-for . 我想以适合C ++ 11 范围的形式转换此代码。
I was thinking of defining a DataEnumerator
wrapper class, whose constructor would call the above InitDataEnumeration()
function. 我在考虑定义一个DataEnumerator
包装类,其构造函数将调用上面的InitDataEnumeration()
函数。
The idea would be to use this wrapper class like this: 想法是使用这样的包装类:
DataEnumerator enumerator{/* init params*/};
for (const auto& data : enumerator)
{
// process data ...
}
How could the former int
-indexed for loop be refactored in the latter range-based form? 如何在后一个基于范围的形式中重构前一个int
-indexed for循环?
I was thinking of exposing begin()
and end()
methods from the enumerator wrapper class, but I don't know what kind of iterators they should return, and how to define such iterators. 我正在考虑从枚举器包装类中公开begin()
和end()
方法,但我不知道它们应该返回什么类型的迭代器,以及如何定义这样的迭代器。
Note that the iteration process is forward-only. 请注意,迭代过程仅向前。
What you are looking for can be done with boost::irange
. 您正在寻找的是可以使用boost::irange
。 It will construct a lazy range of integers in the range [first, last)
and you can just drop it right in like you use i
in your for loop. 它将在[first, last)
范围内构造一个惰性的整数范围,你可以像在for循环中一样使用i
来直接删除它。
for (int i = 0; i < count; i++)
{
EnumGetData(i, &data);
// process data ...
}
Becomes 变
for (auto i : boost::irange(0, count))
{
EnumGetData(i, &data);
// process data ...
}
You require an input iterator this example completely copied from http://en.cppreference.com/w/cpp/iterator/iterator : 您需要一个输入迭代器,此示例完全从http://en.cppreference.com/w/cpp/iterator/iterator复制:
#include <iostream> #include <algorithm> template<long FROM, long TO> class Range { public: // member typedefs provided through inheriting from std::iterator class iterator: public std::iterator< std::input_iterator_tag, // iterator_category long, // value_type long, // difference_type const long*, // pointer long // reference >{ long num = FROM; public: explicit iterator(long _num = 0) : num(_num) {} iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;} iterator operator++(int) {iterator retval = *this; ++(*this); return retval;} bool operator==(iterator other) const {return num == other.num;} bool operator!=(iterator other) const {return !(*this == other);} reference operator*() const {return num;} }; iterator begin() {return iterator(FROM);} iterator end() {return iterator(TO >= FROM? TO+1 : TO-1);} }; int main() { // std::find requires a input iterator auto range = Range<15, 25>(); auto itr = std::find(range.begin(), range.end(), 18); std::cout << *itr << '\\n'; // 18 // Range::iterator also satisfies range-based for requirements for(long l : Range<3, 5>()) { std::cout << l << ' '; // 3 4 5 } std::cout << '\\n'; }
You are right about begin()
and end()
, whatever they return should supply: 你对begin()
和end()
看法是正确的,无论它们返回应该提供什么:
All pretty self-explanatory. 一切都不言自明。
Notice that no traits or categories are required, as would be for iterators intended for some standard library algorithms - just bare minimum. 请注意,不需要任何特征或类别,就像用于某些标准库算法的迭代器一样 - 只是最低限度。
for(auto x : y)
Here, y
must be an object of a class that has a begin()
method and an end()
method that each returns an object implementing the concept of an iterator. for(auto x : y)
这里, y
必须是一个类的对象,该类具有begin()
方法和end()
方法,每个方法都返回一个实现迭代器概念的对象。 The iterator must be incrementable ( iter++
), must be able to accurately determine if it is equal to another iterator of the same kind (via !=
) and must de-reference to whatever x
needs to be. 迭代器必须是可递增的( iter++
),必须能够准确地确定它是否等于同一类型的另一个迭代器(通过!=
),并且必须取消引用任何需要的x
。
This is something you should consider doing if you either A) are bored or otherwise have nothing better to do or B) have a legit need to. 如果您要么A)感到无聊或者没有其他更好的事情要做,或者B)有合法需要,那么您应该考虑这样做。 While this is not difficult to do, neither is it trivial. 虽然这不难做到,但也不是微不足道的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.