插入标准::地图的最佳方法
best way to insert std::map
haveving:
std::map<const std::string,A > cache;
您将如何插入此容器(可以重复尝试(:
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;
}
为什么??(在时间和记忆方面(
你有更好的解决方案吗?
更新:我没有使用 C++11
更新-2:好的,到目前为止,我们意识到:
make_pair
和pair<>
是类似的。
insert
和 [ ]
(带或不带if
检查(都将调用copy
。 所以..是以下之间的竞争:
-
insert
-
[ ]
(带if
检查( -
[ ]
(带if
检查和交换(
你更喜欢哪一个?
再次感谢
我建议emplace
:
template< class... Args >
std::pair<iterator,bool> emplace( Args&&... args );
// usage:
cache.emplace(id, ps);
但是,这有点取决于您是否要第二次插入
失败(如上所述,返回一个
.second
指示成功插入或失败的std::pair<iterator,bool>
- 如果您不在乎,可以忽略它,因为失败的唯一原因是现有键(或覆盖现有值(为此编写
cache[id] = ps;
是最简单且通常完全足够的,但是如果您想避免元素对的默认构造,则可以使用find
然后根据需要覆盖现有或emplace
新元素(。
有时,您可能需要考虑将一个或两个参数标记为 movable-from(即,您不在乎局部变量在emplace
返回后保留在什么(有效(状态,这可能会允许额外的优化(。 从上面的原型中可以看出,使用&&
接受参数,这暗示了执行此类优化的能力。
cache.emplace(std::move(id), std::move(ps));
时间方面明显较差,因为它在实际执行插入时需要在映射中进行两次查找(一次用于find()
,一次用于[]
(。所以坚持使用insert()
功能。
现在的问题是:std::make_pair()
还是std::pair<A, B>()
?遵循 DRY 原则通常是一个好主意,这意味着您不应该重复这些类型,因此请使用 std::make_pair()
。
如果您有 C++11,最好的选择是使用 emplace()
:
cache.emplace(id, ps);
作为旁注,将地图键入为std::map<const std::string, A>
是没有意义的。映射中的键已经是不可变的;只使用std::map<std::string, A>
更简洁(并且不会产生WTF时刻(,并且您很难找到这两者不同的情况。
cache.insert(std::make_pair(id,ps));
这将复制id
和ps
。如果他们有"繁重"的复制构造函数,这将浪费一些时间和内存。
cache.insert(std::pair<std::string,A>(id,ps));
它确实模拟了make_pair
if(cache.find(id) == cache.end()){
cache[id] = ps;
}
最好不检查使用:cache[id] = ps;
.但是,在第一次插入元素时,将构造类型 decltype(ps)
的"默认"对象。然后,将其分配给(使用 operator=
(以ps
。如果它很重,这也可能是问题。但是,我认为如果交换方法不可用,它是首选方式。
cache.emplace(id, ps);
这可能看起来像零拷贝放置,但事实并非如此。 emplace
接收构造函数参数,因此将调用默认的复制构造函数。还有它的C++11。
我认为最有效的方法是
cache[id].swap(ps);
这应该使副本数量最少,但缺点是您的ps
将被重置(或包含旧值(。
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 在C++中向零方向近似的最佳方法
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 检测win32服务创建和删除的最佳方法
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 将线程中的数据存储到全局容器的最佳方法?
- 将一系列整数放入类的最佳方法是什么?
- 在派生类中使用基类的私有成员变量的最佳方法
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- Qt - QVector 和模型视图 - 从列表视图获取自定义类的最佳方法是什么?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- 比较两个节点坐标的最佳方法是什么?
- 在nodejs中使用本机代码的最佳方法是什么?
- 将 pybind11 绑定标记为已弃用的最佳方法
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- C++中变量混叠的最佳方法
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?