【发布时间】:2020-07-08 02:30:24
【问题描述】:
我尝试编写一些自定义函数,而不是允许在 unordered_set 模板中使用我的自定义结构。
我有结构:
struct test_record {
int value;
std::string name;
};
还有哈希运算符:
namespace std {
template<> struct hash<test_record> {
using argument_type = test_record;
using result_type = size_t;
size_t operator()(const test_record& r) const {
const std::hash<std::string> str_hash_fn;
const std::hash<int> int_hash_fn;
const size_t result = str_hash_fn(r.name) ^ int_hash_fn(r.value);
return result;
}
};
};
像这样使用它:
int main()
{
std::unordered_set <test_record> myrecordsset;
myrecordsset.insert({ 1, "one" }); // error!
}
但是编译器会抛出错误信息:
1>E:\开发\视觉 Studio\VC\Tools\MSVC\14.25.28610\include\xstddef(91,22):错误 C2676: 二进制 '==': 'const _Ty' 未定义此运算符或转换 到预定义运算符 1> 和 1>
可接受的类型 [ 1> _Ty=test_record 1> ] 1>E:\开发\视觉 Studio\VC\Tools\MSVC\14.25.28610\include\xstddef(90):消息:同时 编译类模板成员函数'bool std::equal_to::operator ()(const _Ty &,const _Ty &) const' 1> 与 1> [ 1> _Ty=test_record 1>
] 1>E:\开发\视觉 Studio\VC\Tools\MSVC\14.25.28610\include\xhash(164):消息:见 引用函数模板实例化 'bool std::equal_to::operator ()(const _Ty &,const _Ty &) const' 正在编译 1> 与 1> [ 1>
_Ty=test_record 1> ] 1>E:\Development\Visual Studio\VC\Tools\MSVC\14.25.28610\include\xmemory(1318):消息:见 引用类模板实例化 'std::equal_to' 正在编译 1>E:\Development\Visual Studio\VC\Tools\MSVC\14.25.28610\include\xmemory(1318):消息:见 引用变量模板'const bool is_empty_v >' 正在编译 1>E:\开发\视觉 Studio\VC\Tools\MSVC\14.25.28610\include\unordered_set(30):消息: 请参阅对类模板实例化的参考 'std::_Uhash_compare<_kty>' 正在编译 1>
与 1> [ 1> _Kty=test_record, 1>
_Hasher=std::hash, 1> _Keyeq=std::equal_to 1> ] 1>E:\Development\Visual Studio\VC\Tools\MSVC\14.25.28610\include\xhash(342):消息:见 引用类模板实例化 'std::_Uset_traits<_kty>,_Alloc,false>' 正在编译 1> 与 1> [ 1>
_Kty=test_record, 1> _Hasher=std::hash, 1> _Keyeq=std::equal_to, 1> _Alloc=std::allocator 1> ] 1>E:\Development\Visual Studio\VC\Tools\MSVC\14.25 .28610\include\unordered_set(65): 消息: 请参阅对类模板实例化的参考 'std::_Hash,_Alloc,false>>' 正在编译 1> 与 1> [ 1>
_Kty=test_record, 1> _Hasher=std::hash, 1> _Keyeq=std::equal_to, 1> _Alloc=std::allocator 1> ] 1>E:\Development_Projects\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp(20) : 消息:参见对类模板实例化的参考 'std::unordered_set,std::equal_to,std::allocator>' 正在编译
这有什么问题吗?为什么编译器需要在 unordered_set 中使用 equal_to 运算符?
【问题讨论】:
-
您还需要一个
operator==来检查是否相等。自己散列是不够的。由于散列冲突是一回事,标准实现在散列之上使用相等比较。 -
如果您没有相等运算符,您将如何检查是否确实找到了正确的记录,而不仅仅是具有相同哈希的记录?