Using auto (for iteration) in a nested range for a loop

Currently, I started using the auto keyword. I have some doubts about this:

If I need to go through vector , I:

 vector<int>v; for(auto it : v){ cout << it <<endl; } 

But suppose I need to do something like:

 vector<int>v; for(auto it:v){ for(auto jt:X){ //where X is next position of it position //What I mean is if it is currently at 2nd position then //jt iterator will start from 3rd position } } 

I have absolutely no idea how to do this. Suggest what is the appropriate method for this. Thanks in advance.

+5
source share
2 answers

I assume you want to use auto and the new range-based for loop.

You can create vector_view and iterate over the "second vector" in the inner loop.

Here is a simple example to get you started (note the use of auto& , not auto ):

Run it online

 #include <iostream> #include <cstddef> #include <numeric> #include <vector> using std::cout; using std::endl; template <typename T, typename A> struct vector_view { using vector_type = std::vector<T, A>; using const_iterator = typename vector_type::const_iterator; using iterator = typename vector_type::iterator; vector_type& vec; size_t _begin; size_t _length; vector_view(vector_type& v, size_t begin_, size_t length_) : vec(v), _begin(begin_), _length(length_) {} const_iterator begin() const { return vec.begin() + _begin; } iterator begin() { return vec.begin() + _begin; } const_iterator end() const { return vec.begin() + _begin + _length; } iterator end() { return vec.begin() + _begin + _length; } }; int main() { std::vector<int> v(10); std::iota(v.begin(), v.end(), 0); for (auto& it : v) { size_t begin = std::distance(&v[0], &it) + 1; size_t length = v.size() - begin; vector_view<typename decltype(v)::value_type, typename decltype(v)::allocator_type > vv(v, begin, length); cout << it << ": "; for (auto& jt : vv) { cout << jt << " "; } cout << endl; } } 

Output:

 0: 1 2 3 4 5 6 7 8 9 1: 2 3 4 5 6 7 8 9 2: 3 4 5 6 7 8 9 3: 4 5 6 7 8 9 4: 5 6 7 8 9 5: 6 7 8 9 6: 7 8 9 7: 8 9 8: 9 9: 

EDIT . You can make the syntax less verbose if you define the make_vector_view() function:

 template <typename T, typename A> vector_view<T, A> make_vector_view(std::vector<T, A>& v, size_t begin_, size_t length_) { return {v, begin_, length_}; } 

And thanks to the deduction of the type of the template argument, you can write:

Run it online

 for (auto& it : v) { size_t begin = std::distance(&v[0], &it) + 1; size_t length = v.size() - begin; cout << it << ": "; for (auto& jt : make_vector_view(v, begin, length)) { cout << jt << " "; } cout << endl; } 
+3
source
 auto it:v 

is an abbreviation for ...

 auto it = v.begin(); it != v.end(); it++ 

therefore, for using cars inside nested loops, a longer version is more suitable ...

 #include <iostream> #include <vector> using namespace std; int main() { vector<int> v(10, 17); for (auto& it = v.begin(); it != v.end(); ++it) { for (auto& it2 = it + 1; it2 != v.end(); ++it2) { cout << *it2 << " "; } cout << endl; } // system("pause"); return 0; } 
+2
source

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


All Articles