首页 > 解决方案 > map emplace 与 try_emplace 的行为?

问题描述

假设我有一个 unordered_map:

std::unordered_map<Key, BigObject> big_objects;

BigObject就像:

struct BigObject {
    BigObject(P1, P2, P3); // <--- expensive
    /*...*/
};

我有一个Key k, 和一组BigObjects 构造函数的参数P1 p1,P2 p2P3 p3.

如果big_objects已经包含k我什么都不想做。如果big_objects不包含K我要构造和插入BigObject(p1,p2,p3)

是否可以通过一次查找来做到这一点big_objects

即如果密钥已经存在,将emplacetry_emplace构建?BigObject

更新

经过一些测试,它似乎emplace可以构造BigObjecttry_emplace没有?

IE

big_objects[k] = BigObject(p1,p2,p3) // insert k, k now present...

big_objects.emplace(k, p1, p2, p3); // does construct a BigObject

big_objects.try_emplace(k, p1, p2, p3); // does not construct a BigObject

它是否正确?

标签: c++c++17

解决方案


是的,这是正确的,这就是存在的原因try_emplace,如果密钥已经存在,它就不会触及它的论点。

偏好try_emplace

与 insert 或 emplace 不同,如果插入没有发生,这些函数不会从右值参数移动,这使得操作值是仅移动类型的映射变得容易,例如 std::map<std::string, std::独特的_ptr>。此外,try_emplace 将键和参数分别处理为 mapped_type,与 emplace 不同,emplace 需要参数来构造 value_type(即 std::pair)

作为奖励点,您不必使用丑陋的std::piecewise_construct标签来传递键和值构造函数参数(除非您也想就地构造键)。


推荐阅读