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

C++17中如何让map.emplace自动选构造函数及高效使用?

C++17下map相关emplace与高效插入问题解答

1. 修复并简化map<string, st_A>的emplace写法(原case1)

原case1编译失败的核心原因:map的emplace需要构造pair<const string, st_A>,而emplace("c",10,"c")试图传递3个参数给pair的构造——但pair没有接受3个参数的构造函数,无法自动将后两个参数转发给st_A的构造。

最简洁的修复写法:

m1.emplace("c", {10, "c"});

利用C++17的列表初始化,让pair的第二个参数直接通过列表构造st_A,无需显式写出st_A类型(前提是st_A的构造函数非explicit,原代码符合要求)。

如果需要更明确(比如避免潜在歧义),也可以显式构造:

m1.emplace("c", st_A{10, "c"});

2. 复杂容器map<string, deque<pair<int, st_A>>>的简洁emplace写法

对于嵌套容器,结合C++17的类模板实参推导和列表初始化,最简洁的写法是:

map<string, deque<pair<int, st_A>>> m2;
m2.emplace("c1", deque{{1, {10, "c"}}});

编译器会自动推导嵌套的deque、pair和st_A类型,无需全部显式声明。

3. 多构造函数下的简洁emplace是否会导致编译器混淆

当ST_A存在多个构造函数时,明确的列表初始化不会导致混淆:

  • m1.emplace("c", {10}):匹配ST_A(const int)构造函数
  • m1.emplace("c", {"str"}):匹配ST_A(const string&)构造函数
  • m1.emplace("c", {10, "str"}):匹配ST_A(const int, const string&)构造函数

但如果存在参数类型重叠的构造函数(比如ST_A(long)和ST_A(int)),或者列表参数能匹配多个构造函数,会出现编译错误。此时显式指定st_A的构造即可避免歧义:

m1.emplace("c", st_A{10}); // 明确调用int版本构造

4. 高效插入map<string, deque<pair<int, st_A>>>的写法

原insert写法会产生多个临时对象,触发多次构造/拷贝。要实现最高效的插入,需直接在容器内存中构造所有嵌套元素,避免临时对象:

最优方案:try_emplace + 嵌套emplace_back

try_emplace会先检查键是否存在,不存在才构造值对象,完全避免临时开销:

auto [it, inserted] = m2.try_emplace("c1");
if (inserted) {
    // 直接在deque中构造pair和st_A,无临时对象
    it->second.emplace_back(
        std::piecewise_construct,
        std::forward_as_tuple(1),
        std::forward_as_tuple(10, "c")
    );
}

简化高效写法(确定键不存在时)

如果能确定键"c1"不存在,也可以一步完成:

m2.emplace("c1", deque<pair<int, st_A>>{})
    .first->second.emplace_back(1, st_A{10, "c"});

或者进一步简化列表初始化:

m2.emplace("c1", deque{{1, {10, "c"}}});

C++17编译器会优化掉临时对象,效率接近直接构造。


内容的提问来源于stack exchange,提问作者f1msch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:32:29