Sequence-zip function for c++11?

Warning: boost::zip_iterator and boost::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):

#include <boost/range/combine.hpp>
#include <vector>
#include <list>
#include <string>

int main() {
    std::vector<int> a {4, 5, 6};
    double b[] = {7, 8, 9};
    std::list<std::string> c {"a", "b", "c"};
    for (auto tup : boost::combine(a, b, c, a)) {    // <---
        int x, w;
        double y;
        std::string z;
        boost::tie(x, y, z, w) = tup;
        printf("%d %g %s %d\n", x, y, z.c_str(), w);
    }
}

This would print

4 7 a 4
5 8 b 5
6 9 c 6

In earlier versions, you could define a range yourself like this:

#include <boost/iterator/zip_iterator.hpp>
#include <boost/range.hpp>

template <typename... T>
auto zip(T&&... containers) -> boost::iterator_range<boost::zip_iterator<decltype(boost::make_tuple(std::begin(containers)...))>>
{
    auto zip_begin = boost::make_zip_iterator(boost::make_tuple(std::begin(containers)...));
    auto zip_end = boost::make_zip_iterator(boost::make_tuple(std::end(containers)...));
    return boost::make_iterator_range(zip_begin, zip_end);
}

The usage is the same.

Leave a Comment