如何不使用指针将类对象正确插入std::map并解决C2512报错
问题根源
你遇到的编译错误是std::map的operator[]的特性导致的:当你使用m_rooms[key]语法时,如果key不存在于map中,该运算符会先默认构造一个对应值类型的空对象,再把右侧的赋值内容拷贝给这个空对象。
你的Room类显式定义了带参构造函数Room(RoomData, LoggedUser)和拷贝构造函数Room(const Room&),此时C++编译器不会自动生成默认无参构造函数,调用operator[]时找不到可用的默认构造就会抛出C2512错误。
不使用指针的解决方案
两种方案可选,推荐优先使用第一种:
- 方案1:替换
operator[]为不需要默认构造的插入接口
直接使用insert、emplace或try_emplace方法向map插入元素,这些接口不会触发默认构造逻辑,修改createRoom里的代码即可:// 写法1:使用insert m_rooms.insert(std::make_pair(roomData.id, Room(roomData, loggedUser))); // 写法2:使用emplace(C++11及以上,性能更高,直接在容器内存构造对象) m_rooms.emplace(roomData.id, Room(roomData, loggedUser)); // 写法3:使用try_emplace(C++17及以上,key存在时不会构造临时Room对象,更安全) m_rooms.try_emplace(roomData.id, roomData, loggedUser); - 方案2:给Room类补充默认无参构造函数
如果你后续确实需要用到operator[]语法,可以给Room类添加合法的默认构造函数,注意要初始化所有类成员,尤其是RoomData里的const成员timePerPlay:
注意:如果你的业务逻辑不允许存在空的、未初始化的Room对象,不推荐使用这个方案。// 在Room类的public区域添加 Room() = default; // 你当前的RoomData有默认成员初始化、vector成员支持默认构造,所以直接用default即可满足需求,也可以根据业务手动实现默认构造逻辑
额外注意事项
你当前代码里RoomData的timePerPlay是const成员,你自定义的operator=没有给这个成员赋值,后续如果需要对RoomData做赋值操作要注意这个问题,如果你不需要修改该成员可以保留const,否则建议去掉const修饰符。
内容的提问来源于stack exchange,提问作者MrDakik
相关产品推荐
相关产品推荐

