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

如何在unordered_map的try_emplace中正确构造自定义类型?

问题分析

你调用try_emplace时传递的1,1,3是三个int参数,但bar是聚合类型,仅包含int c和foo f两个成员,编译器找不到接受三个int的bar构造函数,因此抛出匹配错误。

解决方案

以下几种方式可以解决编译问题:

方案1:给bar添加构造函数

通过显式构造函数,让try_emplace的参数能匹配到合法的构造逻辑:

#include <iostream>
#include <unordered_map>

using namespace std;

struct foo {
    int a;
    int b;
};

struct bar {
    int c; 
    foo f;
    // 构造函数1:接收int和foo对象
    bar(int c_, foo f_) : c(c_), f(f_) {}
    // 构造函数2:直接接收三个int,拆分初始化c和foo的成员
    bar(int c_, int a_, int b_) : c(c_), f{a_, b_} {}
};

int main()
{
    unordered_map<string, bar> map;
    // 使用构造函数1
    map.try_emplace("hi", 1, foo{1, 3});
    // 使用构造函数2
    map.try_emplace("hello", 2, 4, 5);
    
    return 0;
}

方案2:直接传递bar的聚合初始化实例(C++17+)

如果不想修改结构体定义,在C++17及以上标准中,可以直接传递已初始化的bar对象:

int main()
{
    unordered_map<string, bar> map;
    // 显式构造bar对象
    map.try_emplace("hi", bar{1, foo{1, 3}});
    // 更简洁的聚合初始化写法
    map.try_emplace("hello", bar{2, {4, 5}});
    
    return 0;
}

方案3:用std::forward_as_tuple传递聚合参数(C++17+)

保持bar的聚合类型特性,通过元组传递初始化参数:

#include <tuple> // 需要包含tuple头文件

int main()
{
    unordered_map<string, bar> map;
    map.try_emplace("hi", std::forward_as_tuple(1, foo{1, 3}));
    
    return 0;
}
补充说明

你之前尝试的map.try_emplace("hi", 1, {1, 3})失败,是因为旧版本C++标准中,编译器无法将初始化列表{1,3}作为函数参数推导为foo类型,因此需要显式构造foo对象或使用上述方案规避。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 13:01:03