从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
相关产品推荐
相关产品推荐

