Effective STL 笔记: Item 6--Be alert for C++'s most vexing parse
Introduction to MWB Minor Mode

Effective STL 笔记 -- Item 9: Choose carefully among erasing options

tubo posted @ 2014年9月03日 00:10 in 未分类 , 763 阅读

假设有一个容器中存放着 int ,Container<int> c, 现在想从其中删除数值 1963,可以有如下方法:

1: c.erase(remove(c.begin(), c.end(), 1963), c.end()); // c is continguous memory container
2: c.remove(1963); // c is list
3: c.erase(1963)   // c is standard associative container

对于 continguous memory container 来说, std::remove() 可以保证返回的 iterator 之前的内存中不包含被删除的值,配合 erase 来用,形成所谓的 erase-remove idiom 。而对于 List 来说,应该调用 list 本身的 remove() 方法。对于 map,set 等等,则必须使用 erase() 方法,而不能使用 remove() ,对 associative container 使用 remove() 可能会覆盖容器存储的内容,甚至破坏容器。

假设我们现在想给定一个条件( bool badValue(int x) )并用这个条件来判断有哪些 Entry 需要删除,对 vector、string、deque、list 可以用下列方法:

1: c.erase(remove_if(c.begin(), c.end(), badValue), c.end()); // for vector, string, deque ...
2: c.remove_if(badValue); // for list.

associative container 没有类似的方法,但可以自行遍历删除:

AssocContainer<int> c;
for (AssocContainer<int>::iterator i=c.begin(); i != c.end(); ++i)
    if (badValue(*i))
        c.erase(i); //XXX: This is wrong: when this get executed, iterator will become
                    //XXX: invalid, and ++i will lead to undefined behaviour.

for (AssocContainer<int>::iterator i=c.begin(); i != c.end(); /*Nothing*/)
    if (badValue(*i))
        c.erase(i++); //XXX: This works, because we are passing unincreased value to erase,
                      //XXX: but we get it increased before it was passed to erase().

(使用许可:署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 。)


meidir 说:
2023年10月05日 07:35

I wanted to convey Appreciate delivering this info, you are performing a best wishes while using internet site if you have a possibility do you assist me to make some changes to be able to this site? Not well pay out for the assist, you will find the url in order to this site during my name. Many thanks! 花藝設計

登录 *

loading captcha image...
or Ctrl+Enter