【问题标题】:Benefits of using lower_bound to search a map before insertion. Equivalent for ptr_map?在插入之前使用 lower_bound 搜索地图的好处。等价于 ptr_map?
【发布时间】:2012-11-12 15:50:58
【问题描述】:

在寻找一种仅在键不存在时才插入地图的有效方法时,我遇到了this approach

MapType::iterator lb = mymap.lower_bound(k);

if(lb != mymap.end() && !(mymap.key_comp()(k, lb->first))) {
    // key exists. Value accessible from lb->second
} else {
    // Do insert. Use lb as a hint to insert so it can avoid another lookup
    mymap.insert(lb, MapType::value_type(k, v));
}

这适用于std::map。但是,boost::ptr_map 没有提供与 insert() 类似的形式,即接受迭代器位置的形式。

所以我想知道:

  1. 与直接插入相比,这种方法有什么好处?即

    std::pair<MapType::iterator, bool> ret;
    ret = mymap.insert(MapType::value_type(k, v));
    if (!ret.second) {
        // key exists. insertion not done. do something else
    }
    
  2. 如果确实有充分的理由使用lower_bound 方法,那么boost::ptr_map 是否有等效的策略?还是不适用?

【问题讨论】:

    标签: c++ optimization map boost-ptr-container


    【解决方案1】:

    有两种最有效的方法。

    第一种有效的方法是调用insert(在STL 中也是如此)。这将返回 pair&lt;iterator,bool&gt;,因此如果它已经存在,则不会插入。

    第二种方法,当您必须在密钥不存在时创建对象时使用的方法是使用operator[],它会返回对那里的引用。如果该项目不存在,它会为您插入一个默认创建的值。

    注意这里的区别:对于指向指针的常规 STL 映射,operator[] 将返回一个指针,并插入一个空指针。对于boost::ptr_map,它不会插入空指针,而是会插入指向默认构造对象的指针。

    如果您的集合实际上可能包含默认构造的对象,而您还没有要插入的对象,那么我找不到一种有效的方法来一次性完成。在这种情况下,也许不要使用这个集合,或者确保你的对象被稍微修改,这样你就有某种标志来表明它是“默认构造的”,即一种空状态。

    【讨论】:

    • 有趣的是,它显示我在被问到之前 4 分钟最初回答了这个问题。
    • 非常感谢。在遇到示例中引用的方法之前,您的第一个建议确实是我所使用的。在我尝试比较这两种方法时,它与ptr_map 不一致。我最初的问题写得不是很好,而且有点误导。现在更新了。对不起。
    • “最有效”这个词是有争议的——这取决于用例。创建要插入的对象可能非常昂贵,因此需要先检查,这就是 lower_bound 可以发挥作用的地方。
    • @VladLazarenko 是的,这就是为什么使用法线贴图首先要使用 operator[] 插入。如果您的类型是原始指针或 shared_ptr,将获得一个引用,并且能够确定它已插入,因为您获得了一个空值。您的另一个选择是使用 null 调用 insert() 并查看返回值 。如果你插入的布尔值是真的,那么用新值覆盖迭代器(不是常量)。你不能用 ptr_map 做这两个,虽然它需要一个适当的非常量指针,如果它用 operator[] 插入,则返回一个新创建的指针。
    猜你喜欢
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2021-05-24
    • 2017-11-24
    • 1970-01-01
    相关资源
    最近更新 更多