std::map::try_emplace与emplace行为差异:为何键不存在时多一次移动析构?
std::map::try_emplace 与 emplace 的行为差异测试
常规建议是在几乎所有场景下优先使用std::map::try_emplace而非std::map::emplace。我编写了一个简单测试,追踪调用这两个函数(存在键冲突与无冲突时)的对象创建、拷贝、移动及析构情况,结果显示当键不存在时,try_emplace会导致键额外执行一次移动构造和析构操作。我清楚已移动对象的移动与析构通常成本很低,尤其是对于平凡键,但仍对该结果感到意外,因为这似乎意味着某些场景下emplace可能更高效。
测试代码
#include <map> #include <iostream> struct F { F(int i): i(i) { std::cout << "- ctor (" << i << ")\n"; } ~F() { std::cout << "- dtor (" << i << ")\n"; } F(const F& f): i(f.i) { std::cout << "- copy ctor (" << i << ")\n"; } F(F&& f): i(f.i) { std::cout << "- move ctor (" << i << ")\n"; } F& operator=(const F& f) { i = f.i; std::cout << "- copy (" << i << ")\n"; return *this; } F& operator=(F&& f) { i = f.i; std::cout << "- move (" << i << ")\n"; return *this; } bool operator <(const F& f) const { return i < f.i; } int i{}; }; int main() { std::map<F, F> m; std::cout << "emplace 1:\n"; m.emplace(1, 2); std::cout << "emplace 2:\n"; m.emplace(1, 3); std::cout << "clear:\n"; m.clear(); std::cout << "try_emplace 1:\n"; m.try_emplace(1, 2); std::cout << "try_emplace 2:\n"; m.try_emplace(1, 3); std::cout << "done:\n"; }
测试结果
emplace 1: - ctor (1) - ctor (2) emplace 2: - ctor (1) - ctor (3) - dtor (3) - dtor (1) clear: - dtor (2) - dtor (1) try_emplace 1: - ctor (1) - move ctor (1) - ctor (2) - dtor (1) try_emplace 2: - ctor (1) - dtor (1) done: - dtor (2) - dtor (1)
内容的提问来源于stack exchange,提问作者Alex O
相关产品推荐
相关产品推荐

