可以使用C ++ 11 std::hash
类型来散列函数指针吗? hash
部分特化定义为
template <typename T> struct hash<T*>;
但由于函数指针与C ++中的其他指针类型不同(例如,它们不能转换为void*
),我不确定将它用于类似int(*)()
的类型是否安全}或void(*)(int, int)
。
这是允许的吗?新的ISO规范中是否有任何特定的措辞支持或反驳这一点?
谢谢!
答案 0 :(得分:11)
好问题。我肯定不知道答案,我很乐意推荐给比我更有知识的人,但我的想法是,即使函数指针与数据指针不同,它们仍然是指针:所以应该应用std::hash<T*>
部分专业化。
对于它的价值,以下编译没有警告,即使在g ++ 4.8.1和clang 3.3中使用-pendantic
,并按预期工作:
#include <functional>
#include <iostream>
void func1(int) {}
void func2(int) {}
int main()
{
typedef void (*func_type) (int);
std::hash<func_type> hash;
std::cout << hash(func1) << std::endl;
std::cout << hash(func2) << std::endl;
}
如果有人对该标准有任何提及,我会非常感兴趣。
答案 1 :(得分:1)
我发现了以下内容:
17.6.3.4哈希要求
如果出现以下情况,H类型符合Hash要求:
- 它是一个功能对象类型(20.8)
[...]
然后,引用的20.8状态:
函数对象类型是对象类型(3.9),可以是类型 函数调用中的postfix-expression(5.2.2,13.3.1.1).228 A. function对象是函数对象类型的对象。在这些地方 人们期望将指向函数的指针传递给 算法模板(第25条),指定接口接受 一个功能对象。这不仅使算法模板起作用 指向函数的指针,但也使它们能够随意工作 功能对象。
它有点向后陈述......但语句不仅使算法模板与函数指针一起工作...... 似乎适合你的问题。
答案 2 :(得分:-1)
这实际上很有趣......我在使用MSVC ++时碰到了这个问题。我想做的是:
static std::unordered_map<Fun, std::string> FunctionMap()
{
static std::unordered_map<Fun, std::string> map;
return map;
}
使用Fun函数指针类型。
在编译期间,我收到以下错误:
error C2338: The C++ Standard doesn't provide a hash for this type.
....
_Kty=int (__thiscall Testje::* )(int,int)
在之前的尝试中,我尝试将函数指针强制转换为void*
,这是不允许的,也不会编译(有关详细信息,请参阅:https://isocpp.org/wiki/faq/pointers-to-members#cant-cvt-memfnptr-to-voidptr)。原因是void *是数据指针,而函数指针是代码指针。
到目前为止,我的结论是不允许它,它不会在MSVC ++上编译。