插入std :: map的最佳方法

rah*_*man 1 c++ stl stdmap c++03

有:

std::map<const std::string,A > cache;
Run Code Online (Sandbox Code Playgroud)

你将如何插入这个容器(可以重复尝试):

cache.insert(std::make_pair(id,ps));

cache.insert(std::pair<std::string,A>(id,ps));

if(cache.find(id) == cache.end()){
 cache[id] = ps;
}
Run Code Online (Sandbox Code Playgroud)

为什么??(在时间和记忆方面)

你有更好的解决方案吗?

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

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

make_pair并且pair<>是类似的.

insert[ ](有或没有if检查)都会调用copy.那么......之间的竞争是:

  1. insert
  2. [ ](带if检查)
  3. [ ](带if检查和交换)

你更喜欢哪一个?

再次感谢

Ton*_*roy 6

我建议emplace:

template< class... Args >
std::pair<iterator,bool> emplace( Args&&... args );

// usage:
cache.emplace(id, ps);
Run Code Online (Sandbox Code Playgroud)

但是,这取决于你是否想要第二次插入

  • 失败(如上面会,返回std::pair<iterator,bool>.second指示插入成功或失败-你可以忽略,如果你不介意,因为失败的唯一原因是现有的密钥)或

  • 覆盖现有值(最简单且通常完全适合写入cache[id] = ps;,但如果要避免元素对的默认构造,则可以使用find然后emplace根据需要覆盖现有元素或新元素).

有时您可能需要考虑将一个或两个参数标记为可移动的(即,您不关心emplace返回后局部变量留在什么(有效)状态,这可能允许额外的优化).您可以从上面的原型中看到接受的参数使用&&哪些提示来执行此类优化.

cache.emplace(std::move(id), std::move(ps));
Run Code Online (Sandbox Code Playgroud)


Rei*_*ica 5

第三个在时间上明显较差,因为它在实际插入时需要在地图中进行两次查找(一个用于find(),一个用于[]).所以坚持这个insert()功能.

现在的问题是:std::make_pair()std::pair<A, B>()?遵循DRY的原则通常是一个好主意,这意味着你不应该重复这些类型,所以使用std::make_pair().

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

cache.emplace(id, ps);
Run Code Online (Sandbox Code Playgroud)

作为旁注,输入地图是没有意义的std::map<const std::string, A>.地图中的键已经不可变; 它使用起来更简洁(并且不会产生WTF时刻)std::map<std::string, A>,你会很难找到这两者不同的情况.