With the new range-based for loop we can write code like
for(auto x: Y) {}
Which IMO is a huge improvement from (for ex.)
for(std::vector<int>::iterator x=Y.begin(); x!=Y.end(); ++x) {}
Can it be used to loop over two simultaneous loops, like Pythons zip
function? For those unfamiliar with Python, the code:
Y1 = [1,2,3]
Y2 = [4,5,6,7]
for x1,x2 in zip(Y1,Y2):
print x1,x2
Gives as output (1,4) (2,5) (3,6)
Warning:
boost::zip_iterator
andboost::combine
as of Boost 1.63.0 (2016 Dec 26) will cause undefined behavior if the length of the input containers are not the same (it may crash or iterate beyond the end).Starting from Boost 1.56.0 (2014 Aug 7) you could use
boost::combine
(the function exists in earlier versions but undocumented):This would print
In earlier versions, you could define a range yourself like this:
The usage is the same.
See
<redi/zip.h>
for azip
function which works with range-basefor
and accepts any number of ranges, which can be rvalues or lvalues and can be different lengths (iteration will stop at the end of the shortest range).Prints
0 1 2 3 4 5
std::transform can do this trivially:
If the second sequence is shorter, my implementation seems to be giving default initialized values.
If you have a C++14 compliant compiler (e.g. gcc5) you can use
zip
provided in thecppitertools
library by Ryan Haining, which looks really promising:You can use a solution based on
boost::zip_iterator
. Make a phony container class maintaining references to your containers, and which returnzip_iterator
from thebegin
andend
member functions. Now you can writeExample implementation (please test):
I leave the variadic version as an excellent exercise to the reader.