compare nested iterators after boost transformed()

173 views Asked by At
vector<vector<int>> input{ { { 1, 2 },{ 3, 4 } } };
auto result = input | boost::adaptors::transformed([](const auto& _) {return _; });
result.begin()->begin() == result.begin()->end();

If I run this w/ VS2015 with _ITERATOR_DEBUG_LEVEL=2, then it fires this error in _Compat(const _Myiter& _Right):

        _DEBUG_ERROR("vector iterators incompatible");

This is important because Flattening iterator uses this comparison in advance_past_empty_inner_containers().

What's going on? How do I fix it?

2

There are 2 answers

0
T.C. On

This returns a copy of _: [](const auto& _) {return _; }.

I haven't looked into the code, but it wouldn't surprise me at all if the iterator applies the transformation on each dereference, meaning that each time you dereference result.begin() (with ->) you get a different copy of the vector. Iterators into different vectors are not comparable with each other.

0
Abr001am On

Regardless of this code's behavior that is attempting to compare addresses, I would suppose to initialize an iterator vector<vector<int>>::iteratorto simplify the procedure of comparing first and last values stored in first sub-set ,the last one should be addressed with ->rbegin() or ->end()-1 instead of ->end(), which brings to an unallocated memory span.

Let me repopulate your array, vector<vector<int>> input{ { { 1, 2 },{ 3, 1 } } };

You either do one of these:

assert(*(result.begin()->begin()) == *(result.begin()->end() - 1));
assert(*(result.begin()->begin()) == *(result.begin()->rbegin()));

both throw exceptions since 1=/=2

Try this:

assert(*(result.begin()->begin()) == *((result.end() - 1)->end() - 1));

It doesnt, Since foremost equals forelast stored integer.

Let me know if there is something else not talked about here or not clearly understood .