In maximally generic code, prefer non-member versions of
rbegin, etc., over their member function counterparts.
In C++98, using
const whenever it’s meaningful wasn’t practical: it wasn’t that easy to create them, and once we had one, the ways we could use it were limited. For example:
The code above search for the first occurrence of 1983 (the year “C++” replaced “C with Classes”), then insert the value 1998 (first ISO C++ Standard was adopted) at that location. If no 1983 found, insert at the end of the vector. Since the code never modifies what an
iterator points to, so acoording to the convention to use
const whenever possible, we should use the const-iterator.
However, in C++98, there was no simple way to get a
const_iterator from a non-
const container. To work it out, we might concider using the cast like the following code, which conceptually works but probably won’t compile:
The problem here is that in C++98,
const_iterators weren’t acceptable for insertions and erasures, so we cast
ci into its non-const version. However, in C++98, there’s no portable conversion from a
const_iterator to an
iterator1, so the last statement probably won’t compile. The conclusion:
const_iterators were so much trouble in C++98.
Now that we in the new world of C++11,
const_iterators are both easy to get and easy to use. Even for non-const containers, we get
cend to produce
Maximally Generic Support
Taking into account that some containers and container-like data structures offer
end as non-member functions, C++11 added the non-member functions
end to make sure some generic library code using non-member functions is possible.
C++14 rectified the oversight in C++11, adding the support for
crend. Now we could generalize the code above into a
findAndInsert template as follow:
If we’re using C++11 and want to write maximally generic code, we may build our own implementation for non-member
Point here is: through its reference-to-
container, we are invoking the non-member
begin function (provided by C++11) on a
const container, and this process yields a
const_iterator. In fact, this template works even if
C is a built-in array type2.