地图 emplace 与 try_emplace 的行为?

And*_*zos 3 c++ c++17

假设我有一个 unordered_map:

std::unordered_map<Key, BigObject> big_objects;
Run Code Online (Sandbox Code Playgroud)

哪里BigObject就像:

struct BigObject {
    BigObject(P1, P2, P3); // <--- expensive
    /*...*/
};
Run Code Online (Sandbox Code Playgroud)

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

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

是否可以通过一次查找来完成此操作big_objects

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

更新

经过一些测试后,似乎emplace可以构建BigObject,但try_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
Run Code Online (Sandbox Code Playgroud)

它是否正确?

Qui*_*mby 5

是的,这是正确的,这就是存在的原因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标签来传递键和值构造函数参数(除非您也想就地构造键)。