使用自定义哈希函数插入unordered_set [英] Inserting into an unordered_set with custom hash function
问题描述
我有以下代码来制作 unordered_set< Interval>
。
struct Interval {
unsigned int begin;
unsigned int end;
bool已更新; //如果是concat,则为true。最初是错误的
int patternIndex; //模式索引。对于单一模式
int proteinIndex有效; //蛋白质指数。用于检索模式
};
struct Hash {
size_t operator()(const Interval& interval);
};
size_t Hash :: operator()(const Interval& interval){
string temp = to_string(interval.begin)+ to_string(interval.end)+ to_string(interval.proteinIndex) ;
return hash< string>()(temp);
}
unordered_set< Interval,string,Hash>测试;
但是,当我尝试使用以下代码插入时,我无法编译:
for(list< Interval> :: iterator i = concat.begin(); i!= concat.end(); ++ i){
test.insert((* i));
}
此外,例如,我无法从错误消息中确定问题出在哪里:
注意:候选对象是:
注意:size_t Hash :: operator()(const Interval&)
注意:候选人期望1个论点,2个提供了
我以为我只提供了1个论点...
我的插入代码有什么问题?
这是新的实例化代码: unordered_set< Interval,Hash>测试;
但是,我仍然收到大量错误消息,例如:
注释:候选者是:
注释:size_t Hash :: operator()(const Interval&)< near match>
注意:隐式'this'参数从'const Hash *'到'Hash *'的未知转换
第一个问题
您正在传递字符串
作为实例化 unordered_set<>
类模板的第二个模板参数。 第二个参数应为哈希函子的类型,并为 std ::字符串
不是可调用对象。
也许打算写:
unordered_set< Interval,/ *字符串* /哈希>测试;
// ^^^^^^^^^^^^^
//为什么?
此外,我建议使用开始$ c $以外的名称(成员)变量的c>和
end
,因为它们是C ++标准库的算法名称。
第二个问题:
请记住散列函数应限定为 const
,因此您的函子应为:
struct Hash {
size_t operator()(const Interval& interval)const {
// ^^^^^
//不要忘记这一点!
字符串温度= to_string(interval.b)+
to_string(interval.e)+
to_string(interval.proteinIndex);
返回(temp.length());
}
};
第三个问题:
最后,如果您希望 std :: unordered_set
能够处理间隔 Interval
类型的对象,您需要定义一个与哈希函数一致的相等运算符。默认情况下,如果您没有将任何类型参数指定为 std :: unordered_set
类模板的第三个参数,则 operator ==
将被使用。
您的班级目前没有 operator == 的任何重载
时间间隔
,因此您应该提供一个。例如:
内联布尔运算符==(时间间隔const& lhs,时间间隔const& rhs)
{
return(lhs.b == rhs.b)&&
(lhs.e == rhs.e)&&
(lhs.proteinIndex == rhs.proteinIndex);
}
结论:
在完成所有上述修改后,您可以在此在线示例中看到您的代码正在编译。 / p>
I have the following code to make an unordered_set<Interval>
. This compiles fine.
struct Interval {
unsigned int begin;
unsigned int end;
bool updated; //true if concat. initially false
int patternIndex; //pattern index. valid for single pattern
int proteinIndex; //protein index. for retrieving the pattern
};
struct Hash {
size_t operator()(const Interval &interval);
};
size_t Hash::operator()(const Interval &interval){
string temp = to_string(interval.begin) + to_string(interval.end) + to_string(interval.proteinIndex);
return hash<string>()(temp);
}
unordered_set<Interval, string, Hash> test;
However, I cannot compile when I try to insert using this code:
for(list<Interval>::iterator i = concat.begin(); i != concat.end(); ++i){
test.insert((*i));
}
Moreover, I cannot determine what the problem is from the error messages, for example:
note: candidate is:
note: size_t Hash::operator()(const Interval&)
note: candidate expects 1 argument, 2 provided
I thought I only provided 1 argument...
What is the problem with my insertion code?
Here's the new instantiation code: unordered_set<Interval, Hash> test;
However, I'm still receiving a slew of error messages, for example:
note: candidate is:
note: size_t Hash::operator()(const Interval&) <near match>
note: no known conversion for implicit ‘this’ parameter from ‘const Hash*’ to ‘Hash*’
First problem:
You are passing string
as the second template argument for your instantiation of the unordered_set<>
class template. The second argument should be the type of your hasher functor, and std::string
is not a callable object.
Perhaps meant to write:
unordered_set<Interval, /* string */ Hash> test;
// ^^^^^^^^^^^^
// Why this?
Also, I would suggest using names other than begin
and end
for your (member) variables, since those are names of algorithms of the C++ Standard Library.
Second problem:
You should keep in mind, that the hasher function should be qualified as const
, so your functor should be:
struct Hash {
size_t operator() (const Interval &interval) const {
// ^^^^^
// Don't forget this!
string temp = to_string(interval.b) +
to_string(interval.e) +
to_string(interval.proteinIndex);
return (temp.length());
}
};
Third problem:
Finally, if you want std::unordered_set
to be able to work with objects of type Interval
, you need to define an equality operator consistent with your hash function. By default, if you do not specify any type argument as the third parameter of the std::unordered_set
class template, operator ==
will be used.
You currently do not have any overload of operator ==
for your class Interval
, so you should provide one. For example:
inline bool operator == (Interval const& lhs, Interval const& rhs)
{
return (lhs.b == rhs.b) &&
(lhs.e == rhs.e) &&
(lhs.proteinIndex == rhs.proteinIndex);
}
Conclusion:
After all the above modifications, you can see your code compiling in this live example.
这篇关于使用自定义哈希函数插入unordered_set的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!