粗体
中的更新我正在为函数指针的表编写一个哈希函数,其限制是函数指针和函数表的结构不能被修改(即它们已经发布给第三方)。基于Can std::hash be used to hash function pointers?,std :: hash可用于函数指针。采用它,它产生以下解决方案。
关于这个解决方案的繁琐部分是每次我们向FuncPointers结构添加新的API时,我们必须修改哈希特化以添加相应的更改(即hashFunc(hashedValue,pFuncs-> func3))
我想知道是否有更好的方法来实现函数指针的散列,因此可以避免对散列特化的连续修改?
typedef void (*func_type1) (int);
typedef void (*func_type2) (double);
typedef struct FuncPointers
{
func_type1 func1;
func_type2 func2;
...
} FuncPointers;
template <typename T> void hashFunc (size_t & HashedValue, T funcPointer)
{
std::hash<T> hash;
HashedValue ^= hash(funcPointer); // the XOR operator is randomly picked
}
namespace std
{
template<> struct hash<FuncPointers>
{
size_t operator()(FuncPointers *pFuncs)
{
size_t hashedValue = 0;
hashFunc(hashedValue, pFuncs->func1);
hashFunc(hashedValue, pFuncs->func2);
...
return hashedValue;
}
};
}
答案 0 :(得分:0)
从这开始:https://stackoverflow.com/a/7115547/1774667
它为hash_tuple::hash<Tuple>
提供了std::tuple
,它是一个有效的体面质量哈希(具有组合和递归支持!)。
接下来,按如下方式更改FuncPointers
:
struct FuncPointers:std::tuple<func_type1, func_type2 /*, ...*/> {
// optional:
func_type1 func1() const { return std::get<0>(*this); }
func_type1& func1() { return std::get<0>(*this); }
//...
};
namespace std {
template<>
struct hash<FuncPointers> {
template<typename... Ts>
std::size_t operator()( std::tuple<Ts...> const& funcs ) const {
return hash_tuple::hash<std::tuple<Ts...>>{}(funcs);
}
};
}
重定向std::hash<FuncPointers>
以在hash_tuple::hash<std::tuple<...>>
的父级上调用FuncPointers
。如果您不想继承std::tuple
,则将其更改为has-a而不是is-a关系应该很容易。
可选的func()
访问器使您更接近旧界面(只需添加()
),但也添加了样板。
另一种选择是:
template<unsigned N>
auto func() const->decltype( std::get<N>(*this) ){ return std::get<N>(*this); }
template<unsigned N>
auto& func()->decltype( std::get<N>(*this) ){ return std::get<N>(*this); }
将funcPointers.func1
更改为funcPointers.func<1>()
,但在添加新的func
时会删除大量的样板,并且与funcPointers
的旧接口保持非常相似。
如果使用旧界面的代码不多,则使用std::get<N>()
会有所帮助。
如果您的名称比func1
更具描述性,并且您仅将其用于示例,则函数名称的枚举可以与上面的std::get
或func<X>
一起使用。如果你使用func<X>
,你甚至可以使它类型安全(强制使用命名函数)。
答案 1 :(得分:-1)
最好不要让FuncPointers
成为std::tuple<func_type1, func_type2>
。然后在散列上查看this answer。
BTW,typedef struct FuncPointers { } FuncPointers
是一个C-ism,在C ++中从来就不是必需的。