2017-07-03 0:53 GMT+02:00 Ion GaztaƱaga via Boost
On 30/06/2017 9:03, Andrzej Krzemienski via Boost wrote:
So according to STL rules zip-iterator can only be an InputIterator, even
though you have random-access capability. And in fact, zip-iterator has iterator_category tag of `std::input_iterator_tag`, but apart from that it provides a Boost "traversal category" tag, which just tell how you get to the next object in the colleciton and not about its reference type.
AFAIK Boost.Iterator can define iterator_category as something derived from a standard tag, but that "something" could not be any of standard tags, so I think it's non-conformant.
A container could check through SFINAE if the tag of an iterator is exactly one of the standard provided ones. If Boost.Iterator defines iterator_category to anything that is not exactly a standard tag it won't be accepted by the container.
Those Boost iterators provide two distinct tags: 1. STL-conformant *iterator tag* (in the case of zip-iterator it is `std::input_iterator_tag`) 2. Boost-specific *iterator traversal tag*. So, Boost algorithms take advantage of the *iterator traversal tag*, but the iterator is still recognized as an STL container through the *iterator tag*, and still can be used with STL algorithms. The source of the UB is that `std::prev` *requires* that the iterator passed to it is at least a BidirectionalIterator, and zip-iterator is not (it is a legal OutputIterator). And while it is easy to check this with a type trait at compile-time (and Clang and MSVC do check this), technically not meeting these constraints is an UB, and GCC, because it is not required to check it, indeed does not check it. Regards, &rzej;