C++中unordered_map用operator[]插入Vertex对象失败的原因解析
为什么unordered_map的operator[]会要求Vertex有无参构造函数?
问题的核心在于unordered_map::operator[]和insert的底层行为完全不同:
insert的逻辑:直接把你传入的
Vertex(a)对象(通过拷贝或移动)放入容器中,只需要你的Vertex类型支持拷贝构造/移动构造就行,完全不需要无参构造函数。这也是你用insert能成功的原因。operator[]的逻辑:它的设计目标是「不管键是否存在,都要返回一个对应值的引用」,执行流程是:
- 检查键
a是否在map中存在; - 如果不存在,会自动调用元素类型的无参构造函数,创建一个默认对象绑定到这个键上;
- 返回这个对象的引用,再把右边的
Vertex(a)赋值给这个引用。
- 检查键
而你的Vertex结构体因为已经定义了带参构造函数,C编译器不会自动为它生成默认的无参构造函数(C规则:只要用户定义了任何构造函数,编译器就不再合成默认无参构造)。所以当operator[]尝试默认构造Vertex时,编译器找不到对应的构造函数,就会报错。
举个伪代码对比两者差异:
// insert的等价简化逻辑 auto pair = make_pair(a, Vertex(a)); graph.insert(pair); // 仅用到拷贝构造 // operator[]的等价简化逻辑 if (!graph.contains(a)) { graph.emplace(a); // 此处需要调用Vertex(),你未定义,触发报错 } Vertex& ref = graph.at(a); ref = Vertex(a); // 此处使用赋值运算符
如果一定要用operator[],要么给Vertex添加一个无参构造函数,要么改用emplace或insert来插入元素。
内容的提问来源于stack exchange,提问作者Der Fänger im Roggen
相关产品推荐
相关产品推荐

