使用C++ unordered_set容器编译报错:调用已删除函数
问题描述
我正在用C++完成一门在线开源课程的实验1,使用unordered_set容器时,执行make命令总会报错。
我的代码如下:
定义了Input_data类并想将其存入unordered_set中:
class Input_data { private: std::string _data; uint64_t _index; bool _eof; public: Input_data(const std::string &data, const uint64_t index, const bool eof) : _data(data), _index(index), _eof(eof) {} bool operator<(Input_data &B) { if (this->_index < B._index) { return true; } else { return false; } } };
StreamReassembler类相关代码:
class StreamReassembler { private: size_t _current_index = 0; size_t _current_volume = 0; ByteStream _output; //!< The reassembled in-order byte stream size_t _capacity; //!< The maximum number of bytes std::unordered_set<Input_data> _unsorted_data; public: StreamReassembler::StreamReassembler(const size_t capacity) : _output(capacity), _capacity(capacity), _unsorted_data() {} ... }
报错信息:
In constructor ‘StreamReassembler::StreamReassembler(size_t)’: /mnt/hgfs/AllShare/Cs144/libsponge/stream_reassembler.cc:15:103: error: use of deleted function ‘std::unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set() [with _Value = Input_data; _Hash = std::hash<Input_data>; _Pred = std::equal_to<Input_data>; _Alloc = std::allocator<Input_data>]’ 15 | size_t capacity) : _output(capacity), _capacity(capacity), _unsorted_data() {} | ^~~~~~~~~~~~~~~~
我的g和gcc版本为11,作为C初学者,谷歌了两天仍未找到解决方法,希望得到帮助。
解决方法
问题本质
std::unordered_set是哈希集合,对存储的元素有两个强制要求:
- 必须能计算哈希值:需要对应
std::hash<T>特化或自定义哈希函数 - 必须能判断元素相等:需要
operator==或自定义相等比较器
你的Input_data类既没提供这两个逻辑,标准库也无法自动生成默认实现,导致编译器无法正常初始化unordered_set<Input_data>,触发报错。另外你实现的operator<是给有序容器(如std::set)用的,unordered_set完全不需要这个。
具体修复步骤
1. 添加相等比较运算符operator==
在Input_data的public区域补充:
bool operator==(const Input_data& other) const { // 根据业务需求判断相等逻辑,示例为全成员匹配 return _index == other._index && _data == other._data && _eof == other._eof; }
注意参数和成员函数都要加const,确保能处理常量对象。
2. 提供哈希函数
有两种可选方式:
方式一:特化std::hash模板
在Input_data类定义之后添加:
namespace std { template<> struct hash<Input_data> { size_t operator()(const Input_data& obj) const { // 组合多个成员的哈希值,避免哈希冲突 size_t hash_val = hash<uint64_t>()(obj._index); hash_val ^= hash<string>()(obj._data) << 1; hash_val ^= hash<bool>()(obj._eof) << 2; return hash_val; } }; }
这种方式下,你可以继续使用std::unordered_set<Input_data>的原有声明,无需修改。
方式二:自定义哈希类并在unordered_set中指定
先定义哈希类:
struct InputDataHash { size_t operator()(const Input_data& obj) const { size_t hash_val = std::hash<uint64_t>()(obj._index); hash_val ^= std::hash<std::string>()(obj._data) << 1; hash_val ^= std::hash<bool>()(obj._eof) << 2; return hash_val; } };
然后修改StreamReassembler中的成员声明:
std::unordered_set<Input_data, InputDataHash> _unsorted_data;
额外建议
如果你的需求是按顺序存储元素,那应该用std::set替代std::unordered_set,你已经实现的operator<刚好满足std::set的排序要求,这种情况下不需要哈希函数和operator==,直接替换容器类型即可。
内容的提问来源于stack exchange,提问作者KEIFTH YANG
相关产品推荐
相关产品推荐

