I understand (at least I think I do) that pointers can be used as random STL iterators.
Why does the following code not compile unless I cast the pointer to an iterator?
vector<int> v{1, 2, 3};
v.erase(&v[0]);
I understand (at least I think I do) that pointers can be used as random STL iterators.
Why does the following code not compile unless I cast the pointer to an iterator?
vector<int> v{1, 2, 3};
v.erase(&v[0]);
You can pass pointers to algorithms like std::sort
, std::find
, or std::copy
. These are templates that are configurable for anything that works as an appropriate iterator.
This does not mean that different iterators necessarily convert to each other.
The method erase
of the std::vector<int>
container can only work with iterators to elements of the same vector. As has been pointed out this may be implemented as a pointer, but it usually is not, for reasons stated here:
C++ std::vector<>::iterator is not a pointer, why?
Consider std::find
:
template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );
Here InputIt
is a template parameter. The template std::find
will work with any iterator type that fulfills the requirements of an input iterator, and whose operator*
returns something that can be compared to type T
. Pointers work well here. As Fire Lancer pointed out correctly in a comment, both first
and last
must be of type InputIt
.
Now compare this to std::vector::erase:
iterator erase( const_iterator pos );
This takes a const_iterator
, which is one of the typedefs of the std::vector
class. This is one particular type of iterator, not a template parameter.
The definition of vector.erase(...)
is
iterator erase( const_iterator pos );
The const iterator
is a class in itself.
So if there was a conversion of a plain pointer to this class, then this could be done. But I don't think there is any.
But one thing is to use it in a place where an iterator is expected, and another is to use in algorithms.
Where an iterator
is required, only a iterator can be used.
In algorithms, an iterator
is not expected. Only a object for which a Concept of an iterator is satisified (usually a begin
and end
return the required iterator/pointer).
Although pointers are iterators, they are not the same type as vector iterators (at least they do not have to be).
You can convert a pointer to an element of a vector into an itertor using iterator and pointer arithmetic like this.
std::vector<int> v{1, 2, 3};
int* p = &v[0]; // a pointer
auto v_iter = v.begin() + std::distance(v.data(), p); // an equivalent vector::iterator
v.erase(v_iter);
This only works with contiguous containers like std::vector
or std::array
.