Item 26 from Scott Mayers's "Effective STL" is labeled "Prefer iterator to const_iterator, reverse_iterator and const reverse iterator".
The reasoning is that some forms of insert() and erase() require exactly iterator and converting from the other types is tedious and error-prone. Furthermore, comparing iterator and const_iterator could be problematic, depending on the STL implementation.
The book was released at 2001. Is the advice in Item 26 still valid with the current state of gcc?
The C++14 standard (N3936) guarantees that iterator and const_iterator are freely comparable (§23.2.1 [container.requirements.general]/p7):
In the expressions
i == j i != j i < j i <= j i >= j i > j i - jwhere
iandjdenote objects of a container’siteratortype, either or both may be replaced by an object of the container’sconst_iteratortype referring to the same element with no change in semantics.
In addition, the container member functions take const_iterator parameters as of C++11 (§C.2.13 [diff.cpp03.containers] - as might be inferred from the tag, this is a change from C++03):
Change: Signature changes: from
iteratortoconst_iteratorparametersRationale: Overspecification. Effects: The signatures of the following member functions changed from taking an
iteratorto taking aconst_iterator:
insert(iter, val)forvector,deque,list,set,multiset,map,multimapinsert(pos, beg, end)forvector,deque,list,forward_listerase(iter) forset,multiset,map,multimap`erase(begin, end) forset,multiset,map,multimap`- all forms of
list::splice- all forms of
list::merge
The container requirements have been similarly changed to take const iterators. In addition, it is easy to obtain the underlying iterator from a std::reverse_iterator via its .base() member function. Thus, neither of the concerns noted in the question should be an issue in a conforming compiler.
The advice has been reversed, as can be seen from Item 13 of the upcoming Effective Modern C++ which is titled:
Prefer const_iterators to iterators
The reason is that C++11 and C++14 add several tweaks that make const_iterators a lot more practical:
C++11 adds
cbegin() and cend() (and their reverse counterparts) for all Standard Library containersinsert(), erase()) now take a const_iterator instead of an iterator
C++14 completes that by adding non-member cbegin() and cend() (and their reverse counterparts)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With