在unordered_map中赋值或插入类对象时遇错误求助
嘿,这个场景我太熟悉了!在往std::unordered_map里插入或赋值class2对象时出错,大概率是这几个点没注意到,咱们一个个排查:
1. 拷贝构造函数的访问权限问题
你提到class2有拷贝构造函数,但如果它是**私有(private)或受保护(protected)**的,那std::unordered_map在插入/赋值时根本没法调用它——因为容器内部需要通过拷贝构造来复制class2对象(比如插入时复制临时对象,或者赋值时覆盖已有元素)。
举个反例,这样写肯定会报错:
class class2 { private: // 私有拷贝构造,外部无法访问 class2(const class2& other) {} public: class2() = default; }; class class1 { private: std::unordered_map<std::string, class2> s_list; public: void add_item() { // 这里会触发编译错误:无法访问私有拷贝构造 s_list["key"] = class2(); } };
解决办法:把class2的拷贝构造函数改成public权限。
2. 缺少拷贝赋值运算符
你只提到class2有拷贝构造函数,但std::unordered_map的operator[]赋值操作,除了需要拷贝构造,还需要拷贝赋值运算符(operator=)。如果你没有显式定义它,且class2里有编译器无法自动生成赋值运算符的成员(比如std::unique_ptr这类不可拷贝的对象),就会报错。
比如class2包含unique_ptr时,编译器生成的赋值运算符会被禁用:
class class2 { public: std::unique_ptr<int> data; class2() : data(std::make_unique<int>(0)) {} class2(const class2& other) : data(std::make_unique<int>(*other.data)) {} // 缺少拷贝赋值运算符! };
解决办法:显式实现拷贝赋值运算符,确保能正确复制所有成员:
class2& operator=(const class2& other) { if (this != &other) { *data = *other.data; // 深拷贝内部数据 } return *this; }
3. class2的构造/拷贝逻辑抛出未捕获异常
如果class2的构造函数或拷贝构造函数内部有逻辑会抛出异常,且没有被捕获,那么在unordered_map插入元素时,就会触发异常抛出。比如构造函数里尝试访问空指针、打开不存在的文件等操作。
解决办法:检查class2的构造/拷贝代码,确保异常被正确处理,或者修正逻辑避免抛出未预期的异常。
4. 插入方式的误用
如果你用了emplace这类需要直接构造class2的方法,要确保传入的参数能匹配class2的构造函数。比如class2有一个带std::string参数的构造函数,你却传了不匹配的类型,就会编译报错。
比如:
class class2 { public: class2(const std::string& str) {} }; class class1 { private: std::unordered_map<std::string, class2> s_list; public: void add() { // 错误:emplace的参数不匹配class2的构造函数 s_list.emplace("key", 123); // 正确:传入匹配的string参数 s_list.emplace("key", "hello"); } };
内容的提问来源于stack exchange,提问作者skr

