zoukankan      html  css  js  c++  java
  • Effective STL 笔记 -- Item 9: Choose carefully among erasing options

    假设有一个容器中存放着 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().
        }
        else
        {
            i++;
        }
    }
    
     
  • 相关阅读:
    Android SDK manager 无法更新解决方法
    platform_set_drvdata的源码分析
    从一个男人身上看出他的修养和抱负
    更换RAID1硬盘过程记录
    无线路由器连接有线路由器设置
    在ASP.NET下实现数字和字符相混合的验证码 (转载)
    不走寻常路 设计ASP.NET应用程序的七大绝招
    .NET 2005 使用MasterPages实现Web窗体模板
    用Visual C# 实现四则混合运算(转载)
    如何实施好CRM (转载)
  • 原文地址:https://www.cnblogs.com/yangyingchao/p/3394388.html
Copyright © 2011-2022 走看看