Reputation: 4033
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.
Upvotes: 0
Views: 331
Reputation: 76523
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;
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.
Upvotes: 0
Reputation: 4193
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 checkingoperator[]
: access specified elementfront
: access the first elementback
: access the last elementdata
direct access to the underlying arraybegin
/cbegin
returns an iterator to the beginningend
/cend
returns an iterator to the endrbegin
/crbegin
returns a reverse iterator to the beginningrend
/crend
returns a reverse iterator to the endIn 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.
Upvotes: 9
Reputation: 15951
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…
Upvotes: 1