zip_iterator can be made to model Swappable Iterator (without changing its reference_type) by overloading iter_swap for zip_iterator as follows:
namespace boost { template <typename IteratorTuple> void iter_swap(zip_iterator<IteratorTuple> a, zip_iterator<IteratorTuple> b) { typedef typename zip_iterator<IteratorTuple>::value_type ReferenceTuple; ReferenceTuple ta = *a; ReferenceTuple tb = *b; swap(ta, tb); } }
Inserting that snippet above main() in your code, we now get the desired output:
1 2 100 200
2 1 200 100
I can't think, off the top of my head, of any reason not to add this overload of iter_swap to Boost.
I just realized that, while this will make your example code work correctly, std::sort will still not work because its implementation explicitly qualifies calls to iter_swap as std::iter_swap, rather than making an unqualified call (which would allow the zip_iterator overload to be found by argument-dependent lookup). (At least, GCC 4.7's implementation of std::sort does this). Is this intentional? Regards, Nate