问题描述
As per this question和 ,假设我对容器本身有可变的引用 ,则迭代器的常量可以安全地 使用以下方式删除:
foo::const_iterator cit = ... ;
foo::iterator it = c.erase( cit,cit );
但是,按照以下代码,这似乎不适用于forward_list
的等效项erase_after
:
#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;
}
那么有什么办法可以删除此类的const迭代器的常数?最好不要迭代!
解决方法
您遇到了细分错误,因为您违反了erase_after()
的前提条件,该前提条件是范围(first,last)
传递给了
iterator erase_after(const_iterator first,const_iterator last);
应为有效范围。请注意,这是()
类型的范围,而不是[)
,因此排除了两端。这就是(cit,cit)
对于erase_after
无效的范围的原因。
具有-D_GLIBCXX_DEBUG
complains的GCC:
,错误:函数需要有效的迭代器范围
(__pos,__last)
,__pos
应该在__last
之前并且不等于。{p>
尽管我认为这很棘手,并且STL应该提供一种正常的方法来实现此目的,但是insert_after
也有一个解决方案,因为:
iterator insert_after(const_iterator position,size_type n,const T& x);
前提条件:position为
before_begin()
或[begin(),end())
范围内的可迭代迭代器。效果:在位置后插入
n
的{{1}}副本。返回:迭代器,它指向最后插入的
x
副本或x
的位置。
如果返回n == 0
,则返回pos
。
如果您不想创建n == 0
的临时对象,则可以使用:
T
或
template<class InputIterator>
iterator insert_after(const_iterator position,InputIterator first,InputIterator last);
并提供一个空序列或初始化列表。
,通过迭代,您可以像这样:
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
}