条款9:在删除选项中仔细选择
我们必须保证在调用erase之前就得到了c中下一元素的迭代器。最容易的方法是当我们调用时在i上使用后置递增:
AssocContainer<int> c; ... for (AssocContainer<int>::iterator i = c.begin(); // for循环的第三部分 i != c.end(); // 是空的;i现在在下面 /*nothing*/ ){ // 自增 if (badValue(*i)) c.erase(i++); // 对于坏的值,把当前的 else ++i; // i传给erase,然后 } // 作为副作用增加i; // 对于好的值, // 只增加i
我们必须对vector、string和deque采用不同的战略。特别是,我们必须利用erase的返回值。那个返回值正是我们需要的:一旦删除完成,它就是指向紧接在被删元素之后的元素的有效迭代器。换句话说,我们这么写:
for (SeqContainer<int>::iterator i = c.begin(); i != c.end();){ if (badValue(*i)){ logFile << "Erasing " << *i << '\n'; i = c.erase(i); // 通过把erase的返回值 } // 赋给i来保持i有效 else ++i; }
为了避免你奇怪list的适当方法是什么,事实表明对于迭代和删除,你可以像vector/string/deque一样或像关联容器一样对待list;两种方法都可以为list工作。