标准应是这样的:
for (iter = valmap.begin(); iter != valmap.end(); )
{
if (3 == *iter)
valmap.erase(iter++); //说是传给erase的是iter的一个副本?iter++是下一个有效的迭代器
else
++iter;
}
问1:valmap.erase(iter++); 为什么不等价于valmap.erase(iter); iter++;又不等价于呢valmap.erase(++iter);?
问2:不能理解副本的说法,如果
erase(iter)
{
副本=iter;
删除iter的内容;
iter=副本;
}
然后在哪一步执行iter++时,但是iter的内容被删除了会错误把?难道和树结构有关?
/////////////////////////////
如果是
erase(iter)
{
副本=++iter;
删除iter的内容;
iter=副本;
}
这样能说通了,不过此时调用
valmap.erase(iter); //无++
就好了吧?
让我们先来看一下下面的代码。
C++中类的++运算符调用的是operator++这个函数,其中带无名int参数的是后置时调用,无参数的是前缀时调用。
调用前缀++运算符时,对象做++的逻辑(具体做什么要看具体的类)然后再返回对象,最后返回的是++操作后的对象。
调用后置++运算符时,对象先保留一份旧值,然后做++逻辑,最后返回对象++操作前的旧值。
从上面的说明valmap.erase(iter++)的调用是执行了两个函数,先调用iter对象的operator++(int)函数然后再调用valmap.erase()函数,valmap.erase()的参数为iter对象调用operator++(int)的返回值,那么现在就非常清楚了valmap.erase(iter++);先让迭代器iter对象指向map中的下一个元素,然后返回迭代器的旧值,最后再删除旧的迭代器关联的元素。
有了上面两点说明,我们就知道如何回答问题1和问题2了。
问题1
valmap.erase(iter++); 和valmap.erase(iter); iter++;和valmap.erase(++iter);都是不相同的。
valmap.erase(iter++); 的调用顺序:operator++(int)->valmap.erase()。valmap.erase(iter); iter++; 的调用顺序:valmap.erase()->operator++(int)。valmap.erase(++iter); 的调用顺序:operator++()->valmap.erase()。
问题2
问题1理解透彻了,问题2也就不用再多说了。