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 - j
where
i
andj
denote objects of a container’siterator
type, either or both may be replaced by an object of the container’sconst_iterator
type 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
iterator
toconst_iterator
parametersRationale: Overspecification. Effects: The signatures of the following member functions changed from taking an
iterator
to taking aconst_iterator
:
insert(iter, val)
forvector
,deque
,list
,set
,multiset
,map
,multimap
insert(pos, beg, end)
forvector
,deque
,list
,forward_list
erase(iter) for
set,
multiset,
map,
multimap`erase(begin, end) for
set,
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