Here is the solution to the eagles in a semi-tribal form.
template<typename ForwardIterator, typename DestItr> auto cartesian_product(ForwardIterator b, ForwardIterator e, DestItr d) -> DestItr { using std::next; using std::for_each; for (; b != e; ++b) { for_each(next(b), e, [&](auto right){ *d++ = std::make_tuple(*b, right); }); } return d; } template<typename ForwardRange, typename DestItr> auto cartesian_product(ForwardRange r, DestItr d) -> DestItr { using std::begin; using std::end; return cartesian_product(begin(r), end(r), d); }
Live on Coliru.
You could, of course, make it more universal if you use overloads for custom functors instead of make_tuple and the assignment operator. Standard library algorithms tend to do this. If I wrote this for the library, I would do it too.
source share