You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:55:01