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