As per this question , and assuming I have a mutable reference to the container itself , the constness of an iterator can be safely removed using:
foo::const_iterator cit = ... ;
foo::iterator it = c.erase( cit, cit );
However, this doesn't seem to work for forward_list
's equivalent, erase_after
, as per this code::
#include <iostream>
#include <forward_list>
typedef std::forward_list<int>::const_iterator CIT;
typedef std::forward_list<int>::iterator IT;
int main()
{
std::forward_list<int> m{1, 2, 3};
CIT cit = m.begin();
IT it = m.erase_after(cit, cit); // Segmentation fault!
std::cout << *it;
}
So is there any way to remove the constness of a const iterator for this class? Preferably not by iteration!
You have a segmentation fault because you're violating the precondition of erase_after()
, which states that the range (first, last)
passed to
iterator erase_after(const_iterator first, const_iterator last);
should be a valid range. Note that this is ()
-type of range, not [)
, so both ends are excluded. That's why (cit, cit)
is not a valid range for erase_after
.
GCC with -D_GLIBCXX_DEBUG
complains :
Error: function requires a valid iterator range
(__pos, __last)
,__pos
shall be before and not equal to__last
.
although I think it's tricky and STL should provide a normal way to do that, there is also a solution by insert_after
, because:
iterator insert_after(const_iterator position, size_type n, const T& x);
Preconditions: position is
before_begin()
or is a dereferenceable iterator in the range[begin(), end())
.Effects: Inserts
n
copies ofx
after position.Returns: An iterator pointing to the last inserted copy of
x
or position ifn == 0
.
it returns pos
itself, if n == 0
.
if you don't want to create a temporary object of T
, you can use:
template<class InputIterator>
iterator insert_after(const_iterator position, InputIterator first, InputIterator last);
or
iterator insert_after(const_iterator position, initializer_list<T> il);
and provide an empty sequence or initializer list.
By iteration you can do it like:
IT it (m.begin());
for ( CIT cit = m.begin(); cit != m.end(); ++cit )
{
std::advance (it, std::distance<CIT>(it, cit ) );
// do changes on it
}
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.