Up until a few days ago I thought all 'position' related member functions of a vector
returned an iterator
. I found out recently that while insert()
and erase()
functions do indeed return iterators
, begin()
and end()
do so by definition, but functions like at()
, front()
, back()
do not do so, they return a simple reference.
While references make life easier as I would not have to dereference the iterator
fist, to me it still seems inconsistent that some member functions are returning a reference instead of an iterator. If anything, C++ tries to minimize inconsistencies like this by providing the bare minimum while still maintaining ease in programming.
at
method is from the group of common container methods called 'Element access', those return reference, pointers. There is another group of common container methods called 'Iterators', those return iterators. It is clear, simple and well-known design decision for the standard library.
at
: access specified element with bounds checking operator[]
: access specified element front
: access the first element back
: access the last element data
direct access to the underlying array begin
/ cbegin
returns an iterator to the beginning end
/ cend
returns an iterator to the end rbegin
/ crbegin
returns a reverse iterator to the beginning rend
/ crend
returns a reverse iterator to the end In the iterator concept, elements within iterator range are accessed through std::advance
method of STD. This would work for InputIterator
s, for BST, list, vectors, etc., of course with different complexity.
begin()
, end()
, insert()
, erase()
, etc. are methods that work on the vectors' sequence of elements itself, while operator []
, at()
, front()
, and back()
are methods that access concrete elements of this sequence. I don't really see an inconsistency here. They exist for all sequence containers and they always do conceptually the same thing. Sure, you could implement something like front()
and back()
yourself, nothing keeps you from doing so. They are by definition equivalent to dereferencing begin()
and prev(end())
respectively. They exist for convenience. Depending on how far you want to go, std::vector
itself exists just for convenience…
The abstraction that the Standard Template Library presents is sequences , iterators , and algorithms . Container are one way of creating and managing sequences, but they are not the only way. For example, an input stream can be used as a sequence, by creating a std::istream_iterator
. But things like int i; double d; std::cin >> i >> d;
int i; double d; std::cin >> i >> d;
would be rather awkward to write if std::cin
only defined an iterator-based interface. Same thing for containers: they're useful in contexts other than iteration, and they define interfaces appropriate to their general uses; one of those uses is as a sequence for STL algorithms, but there are other uses, too.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.