Is there a short way to write for i in the range (100) in C ++?

If I got this right, I could use it to iterate over a fixed range:

for(int i: {1, 2, 3, 4, 5}) do_sth(i); 

And this is the same thing:

 vector<int> v{1, 2, 3, 4, 5}; for(int i: v) do_sth(i); 

But what if I want to iterate over the range 1, ..., 100 and already know what during compilation? What is the most beautiful way to do this? Which is the most effective? Which is the shortest?

Edit: Of course, I could write a regular loop, but the actual use case would include more complex content than int s.

I simplified the example a bit.

+6
source share
6 answers

You can "easily" write a class compatible with a range that represents an integer range. You just need to write iterators for this.

Or you can use Boost.Range counting_range , as it is.

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

?

+16
source

If you really want it in a container, you can fill the container using the std::iota . Otherwise, use the regular for loop.

+4
source

Use range for function template:

 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>{}); } 

Example:

 for (auto i : range<5>()) { do_sth(i); } 
+1
source

An example of an iterator-based method mentioned by 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; }; 

Then it can be used as follows:

 for(int i : range(0, 100)) { printf("%d\n", i); } 
+1
source
 #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"; } 

Great execution overhead, error prone (mostly my implementation) ... the way I like it!

But it solves the problem and even has a non-ugly syntax :)

0
source

Source: https://habr.com/ru/post/954066/


All Articles