我想替换一个简单的for循环:
for (auto i=0;i<n;i++) {
whatever;
}
Run Code Online (Sandbox Code Playgroud)
使用以下形式的迭代器:
for (auto i: <something>) ...
Run Code Online (Sandbox Code Playgroud)
我知道它可以用向量完成,但我不想声明一个向量(并填充它).
从理论上讲,我想要一些简单的东西:
for (auto i: 1..n) ...
Run Code Online (Sandbox Code Playgroud)
这可能吗?
谢谢.
没有内置解决方案.
如果你愿意,你可以像这样使用Boost.counting_range:
#include <iostream>
#include <boost/range/counting_range.hpp>
int main() {
for (auto v : boost::counting_range(2,13))
std::cout << v << "\n";
}
Run Code Online (Sandbox Code Playgroud)
(现场)或自己动手.增强范围不会保存所有数字,而是包装一对迭代器.(概念上类似于Python2 xrange或Python3 range.)
现在,这是否比手动编写循环更容易/更好是供读者决定的.
附录:如果要推出自己的解决方案,请编写一些迭代器,在取消引用时返回一个数字,在增量时增加内部数字,如果内部数字相等则比较相等.然后编写一个包装类,它提供begin并end返回这些迭代器的函数.
Boost.counting_iterator是这种迭代器的实现,Boost.counting_range将其包装为如上所示的范围.
template<class T>
struct index_it{
T t;
void operator++(){++t;}
T operator*()const{ return t; }
friend bool operator==(index_it const& lhs,index_it const& rhs){
return lhs.t==rhs.t;
}
friend bool operator!=(index_it const& lhs,index_it const& rhs){
return lhs.t!=rhs.t;
}
};
template<class T>
index_it<T> index(T t){return {t}; }
Run Code Online (Sandbox Code Playgroud)
这是一个非常小的索引"迭代器".它并不是一个真正的迭代器,因为它违反了它们的公理:但它保证足够一个for(:)循环.
template<class It>
struct range_t{
It b,e;
It begin()const{return b;}
It end()const{return e;}
};
template<class It>
range_t<It> range(It b, It e){ return {b,e}; }
Run Code Online (Sandbox Code Playgroud)
是一个非常小的范围,有资格获得for(:)循环.
template<class Scalar>
auto indexes(Scalar b, Scalar e){
return range(index(b),index(e));
}
Run Code Online (Sandbox Code Playgroud)
制作一系列索引.
使用:
for(auto i:indexes<int>(0,n))
Run Code Online (Sandbox Code Playgroud)
为了好玩,这也给了我们:
template<class R>
auto iterators(R& r){
using std::begin; using std::end;
return indexes( begin(r), end(r) );
}
Run Code Online (Sandbox Code Playgroud)
这允许您迭代容器或范围的有效迭代器,就像那样.一旦你弄清楚究竟index_it是什么,问题就是同一个问题!
for(auto it:iterators(vec))
Run Code Online (Sandbox Code Playgroud)
实例.