C++ 插入std::map的最佳方法

C++ 插入std::map的最佳方法,c++,stl,stdmap,c++03,C++,Stl,Stdmap,C++03,具有: std::map<const std::string,A > cache; std::map缓存; 您将如何插入此容器(可能会重复尝试): cache.insert(std::make_pair(id,ps)); insert(std::pair(id,ps)); if(cache.find(id)=cache.end()){ cache[id]=ps; } 为什么??(在时间和记忆方面) 你有更好的解决办法吗 更新: 我没有使用C++11 更新-2: 好的,到目前为止

具有:

std::map<const std::string,A > cache;
std::map缓存;
您将如何插入此容器(可能会重复尝试):

cache.insert(std::make_pair(id,ps));
insert(std::pair(id,ps));
if(cache.find(id)=cache.end()){
cache[id]=ps;
}
为什么??(在时间和记忆方面)

你有更好的解决办法吗

更新: 我没有使用C++11

更新-2: 好的,到目前为止,我们意识到:

make\u pair
pair
是类似的

插入
[]
(如果检查有无
)都将调用
复制
。所以竞争是在:

  • 插入
  • []
    (使用
    if
    检查)
  • []
    (带
    if
    检查和)
  • 你喜欢哪一个

    再次感谢

    我建议:

    我建议:


    第三种方法在时间上明显较差,因为它在实际执行插入时需要在映射中进行两次查找(一次用于
    find()
    ,另一次用于
    []
    )。因此,请坚持使用
    insert()
    函数

    现在的问题是:
    std::make_-pair()
    std::pair,这意味着不应该重复这些类型,所以使用
    std::make_-pair()

    如果您有C++11,最好的选择是使用
    emplace()



    作为旁注,将映射键入
    std::map
    是没有意义的。映射中的键已经是不可变的;只使用
    std::map
    更为简洁(并且不会产生WTF时刻),您将很难找到这两种方法不同的情况。

    第三种方法在时间上明显较差,因为在实际执行插入时需要在map中进行两次查找(一次用于
    find()
    ,另一次用于
    []
    )。因此,请坚持使用
    insert()
    函数

    cache.insert(std::make_pair(id,ps));
    
    现在的问题是:
    std::make_-pair()
    std::pair,这意味着不应该重复这些类型,所以使用
    std::make_-pair()

    如果您有C++11,最好的选择是使用
    emplace()


    作为旁注,将映射键入
    std::map
    是没有意义的。映射中的键已经是不可变的;只使用
    std::map
    更简洁(并且不会产生WTF时刻),您将很难找到两者不同的情况

    cache.insert(std::make_pair(id,ps));
    
    这将复制
    id
    ps
    。如果他们有“重”拷贝构造函数,这将浪费一些时间和内存

    cache.insert(std::pair<std::string,A>(id,ps));
    
    最好不用检查就使用:
    cache[id]=ps。但是,在第一次元素插入时,将构造类型为
    decltype(ps)
    的“默认”对象。然后,将其赋值(使用
    运算符=
    )到
    ps
    。如果它很重,这也可能是个问题。但是,如果交换方法不可用,我认为它是首选方法

    cache.emplace(id, ps);
    
    这看起来像是零拷贝安置,但它不是<代码>模板
    接收构造函数参数,因此将调用默认副本构造函数。还有它的C++11

    我认为最有效的方法是

    cache[id].swap(ps);
    
    这应该可以制作最少数量的副本,但缺点是您的
    ps
    将被重置(或包含旧值)

    这将复制
    id
    ps
    。如果他们有“重”拷贝构造函数,这将浪费一些时间和内存

    cache.insert(std::pair<std::string,A>(id,ps));
    
    最好不用检查就使用:
    cache[id]=ps。但是,在第一次元素插入时,将构造类型为
    decltype(ps)
    的“默认”对象。然后,将其赋值(使用
    运算符=
    )到
    ps
    。如果它很重,这也可能是个问题。但是,如果交换方法不可用,我认为它是首选方法

    cache.emplace(id, ps);
    
    这看起来像是零拷贝安置,但它不是<代码>模板
    接收构造函数参数,因此将调用默认副本构造函数。还有它的C++11

    我认为最有效的方法是

    cache[id].swap(ps);
    

    这应该可以制作最少数量的副本,但缺点是您的
    ps
    将被重置(或包含旧值)。

    cache[id]=ps无check@BryanChen但是,如果您有C++11,那么这会改变cache.emplace(id,ps)
    的语义。显然不是最后一个,因为它在地图上搜索了两次。当然也不是第二个,因为第一个是一个更干净、更精简的写作方式。嗯,也许我应该写一个答案。@BryanChen
    insert()
    不会更改元素(如果元素已经存在)。cache.insert(std::pair(id,ps))不会转发该值,而是复制它,因为map的值类型是std::pair。注意const.
    cache[id]=ps无check@BryanChen但是,如果您有C++11,那么这会改变cache.emplace(id,ps)
    的语义。显然不是最后一个,因为它在地图上搜索了两次。当然也不是第二个,因为第一个是一个更干净、更精简的写作方式。嗯,也许我应该写一个答案。@BryanChen
    insert()
    不会更改元素(如果元素已经存在)。cache.insert(std::pair(id,ps))不会转发该值,而是复制它,因为map的值类型是std::pair。请注意常量。根据重复键上所需的行为,
    []
    可能会更好。尽管给出了有问题的
    if
    保护,但这可能是没有意义的。@Xarn
    std::map
    不允许重复键。当键已经存在时,OP的所有3个示例都保持值不变,所以我假设这是预期的行为。
    []
    在这种情况下能更好吗?
    std::map::value\u type(id,ps)
    make\u对
    解决方案好得多。根据对重复密钥的所需行为,
    []
    可以更好。尽管给出了有问题的
    if
    防护装置,
    cache[id].swap(ps);