Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion about incrementing iterator

Tags:

c++

iterator

int main(){
        multiset<string> graph;

        graph.insert("a");
        graph.insert("b");
        multiset<string>::iterator it = graph.begin();
        cout << *(it + 1) // Wrong
        cout << *++it;    // True
        return 0;

}

why does the compiler complain when executing *(it + 1), but *(++it) can be well executed. Shouldn't it + 1 and ++it return the same value?

like image 336
o o Avatar asked Dec 10 '22 23:12

o o


2 Answers

RandomAccessIterators allow you to add arbitrary offsets like it + n, but multiset has only BidirectionalIterators. For more on iterator categories see here: https://en.cppreference.com/w/cpp/iterator#Iterator_categories.

In principle you are correct, that it+1 and ++it both increment the iterator by one. And if an iterator supports ++it it could also support it+n. However, the idea is that RandomAccessIterators can perform it+n in constant time, while iterators that are not RandomAccessIterators would need to perform n-times single increments. Because that is rather inefficient they do not support it out of the box.

If you want to increment a non-RandomAccessIterator by more than 1 you can use std::next or std::advance. By calling std::next/std::advance the code more clearly expresses that incrementing the iterator is a potentially expensive operation, while it + n is expected to take constant time (hence not allowed when it does not take constant time).

like image 175
463035818_is_not_a_number Avatar answered Dec 12 '22 13:12

463035818_is_not_a_number


Because std::multiset iterator needs to satisfy requirements of BidirectionalIterator, which means that it must support operator++ and operator--. There is no requirement to support other operations, like addition or subtraction.

like image 26
pptaszni Avatar answered Dec 12 '22 14:12

pptaszni