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

从unordered_map获取struct A时触发‘已删除函数非法使用’错误排查

解决unordered_map获取对象时的"illegal use of deleted function"错误

这个问题我之前帮同事排查过,核心原因和你想的不太一样——问题出在unordered_map::operator[]的特殊行为上,而非你以为的拷贝构造环节。

为什么会触发默认构造函数?

unordered_map的operator[]有个容易踩坑的逻辑:当你访问的key不存在时,它会自动在map中插入一个默认构造的A实例,然后返回这个实例的引用。如果你的类A因为以下任一原因导致默认构造函数被删除了,就会触发这个错误:

  • A显式声明了= delete的默认构造函数;
  • A包含了没有默认构造函数的成员变量(比如另一个只能通过带参构造初始化的类);
  • A继承了没有默认构造函数的基类。

你提到以为是拷贝构造场景,其实是误解了流程:错误发生在operator[]试图创建新对象的阶段,还没到后续的赋值环节。

怎么解决?

根据你的需求,有两种常见方案:

方案1:避免自动插入,改用安全的查找方式

如果你只需要访问已存在的元素,别用operator[],改用这两个方法:

  • find():返回迭代器,找不到时等于unordered_map::end(),需要自己判断:
    auto it = my_map.find(key);
    if (it != my_map.end()) {
        A& obj = it->second;
        // 操作obj
    } else {
        // 处理key不存在的情况
    }
    
  • at():直接返回对应元素的引用,找不到时会抛出std::out_of_range异常,适合你确定key一定存在的场景:
    try {
        A& obj = my_map.at(key);
        // 操作obj
    } catch (const std::out_of_range& e) {
        // 处理key不存在的异常
    }
    

方案2:给类A添加可用的默认构造函数

如果你确实需要operator[]的自动插入功能,那就要确保A有合法的默认构造函数:

  • 如果是因为成员变量无法默认构造,要么给成员变量添加默认构造,要么在A的默认构造中初始化这些成员:
    class A {
    public:
        // 显式定义默认构造函数,初始化成员
        A() : some_member(0) {}
        // 你的其他构造函数
        A(int val) : some_member(val) {}
    private:
        int some_member;
    };
    
  • 如果之前显式删除了默认构造,把A() = delete;去掉即可。

错误复现的例子

比如你的类A是这样的:

class A {
public:
    A(int x) : num(x) {} // 只有带参构造,没有默认构造
private:
    int num;
};

std::unordered_map<int, A> my_map;
my_map[1] = A(10); // 这里会报错:illegal use of deleted function

这里my_map[1]会先尝试默认构造A,但A没有默认构造,所以触发错误。改成my_map.emplace(1, A(10))或者用find就不会有问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:05:53