6

如果我做对了,我可以用它来迭代一个固定的范围:

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循环,但实际用例会涉及比ints更复杂的内容。

我只是稍微简化了这个例子。

4

6 回答 6

16
for( int i = 1; i <= 100; ++i )
{
    do_sth( i );
}

?

于 2013-09-18T12:37:56.170 回答
4

如果你真的想要它在一个容器中,你可以使用该std::iota函数填充一个容器。否则使用正常for循环。

于 2013-09-18T12:38:23.663 回答
4

您可以“轻松”编写一个与 for-range 兼容的类来表示整数范围。你只需要为它编写迭代器。

或者你可以使用Boost.Range'scounting_range,就是这样。

于 2013-09-18T12:42:36.347 回答
1

将 range-for 与函数模板一起使用:

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);
}
于 2013-09-18T12:45:39.823 回答
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);
}
于 2013-10-24T21:47:37.297 回答
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";
}

运行时开销大,容易出错(主要是我的实现)......就像我喜欢的那样!

但它确实解决了问题,甚至有一个不那么难看的语法:)

于 2013-09-18T13:31:21.433 回答