Here is orlp's solution in semi-generic 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 generic by having overloads for custom functors to use instead of make_tuple
and the assignment operator. The standard library algorithms tend to do so. Were I writing this for a library, I'd probably do so as well.
X
you want{(x1,x2) | x1,x2 ∈ X, x1 ≠ x2}
? Did I read that right? – Moderato[0,1],[1,2][2,3]...
) or do you want[0,1],[2,3][4,5]...
? – Lucilelucilia2
of thestd::unordered_set
? – Stow