如果我做对了,我可以用它来迭代一个固定的范围:
for(int i: {1, 2, 3, 4, 5})
do_sth(i);
这是同样的事情:
vector<int> v{1, 2, 3, 4, 5};
for(int i: v)
do_sth(i);
但是如果我想迭代1,...,100的范围并且在编译时已经知道怎么办? 最美妙的方法是什么? 效率最高的是什么? 什么是最短的?
编辑:当然我可以编写一个常规的for循环,但实际的用例会涉及比int
更复杂的内容。
我稍微简化了一下这个例子。
答案 0 :(得分:16)
for( int i = 1; i <= 100; ++i )
{
do_sth( i );
}
答案 1 :(得分:4)
如果您真的想要它在容器中,可以使用std::iota
函数填充容器。否则使用正常的for
循环。
答案 2 :(得分:4)
您可以“轻松”编写表示整数范围的范围兼容类。你只需要为它编写迭代器。
或者你可以使用Boost.Range's counting_range
,就是这样。
答案 3 :(得分:1)
对函数模板使用范围:
namespace detail
{
template <int... Is>
struct index { };
template <int N, int... Is>
struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
template <int... Is>
struct gen_seq<0, Is...> : index<Is...> { };
}
template <int... Is>
std::array<int, sizeof...(Is)> range(detail::index<Is...>)
{
return {{ Is... }};
}
template <int N>
std::array<int, N> range()
{
return range(detail::gen_seq<N>{});
}
示例:
for (auto i : range<5>())
{
do_sth(i);
}
答案 4 :(得分:1)
基于迭代器的技术示例,正如Sebastian Redl所说:
class range {
public:
struct rangeIt{
rangeIt(int v) : _v(v){}
int operator*()const{return _v;}
void operator++(){_v++;}
bool operator!=(const rangeIt & other)const{ return _v != other._v;}
private:
int _v;
};
range(int a, int b):_a(a),_b(b){}
rangeIt begin() const { return rangeIt(_a); }
rangeIt end() const { return rangeIt(_b); }
private:
int _a, _b;
};
然后就可以这样使用:
for(int i : range(0, 100)) {
printf("%d\n", i);
}
答案 5 :(得分:0)
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> operator"" _r(const char* text, const size_t)
{
string txt(text);
auto delim = txt.find('-');
auto first = txt.substr( 0, delim);
auto second = txt.substr(delim + 1);
int lower = stoi(first);
int upper = stoi(second);
vector<int> rval(upper - lower);
generate(rval.begin(), rval.end(), [&]{ return lower++; } );
return rval;
}
int main()
{
for(auto& el : "10-100"_r)
cout<<el<<"\n";
}
运行时开销大,容易出错(主要是我的实现)......就像我喜欢它一样!
但它确实解决了问题,甚至还有一种不那么丑陋的语法:)