Confusion about incrementing iterator

Viewed 107
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?

4 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).

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.

An iterator is an object that fit with the structure, each iterator works differently depends on what structure you're using (map, set, vector,..).

An iterator is defined with functions, in C++ you can overload operators like +,-,*,(),[],... , so maybe ++ function as been defined not like the operator +(iterator, int) which result an error.

If you support + 1, you have to also support + N. To make it harder to write inefficient code, + N is only supported for iterators for which it works in constant time (e.g. it's supported for std::vector).

Related