C++ std::hash可以用来散列函数指针吗?

C++ std::hash可以用来散列函数指针吗?,c++,pointers,c++11,hash,stdhash,C++,Pointers,C++11,Hash,Stdhash,C++11std::hash类型能否用于散列函数指针?有一个散列部分专门化定义为 template <typename T> struct hash<T*>; 模板结构哈希; 但是由于函数指针与C++中的其他指针类型不同(例如,它们不能被转换成 Value*/COD>),所以我不能确定它是否适合使用诸如“代码> int(*)())/>代码>或空洞(*)(int,int)< /> > < < 这是允许的吗?新的ISO规范中是否有支持或反驳这一点的具体措辞 谢谢 好问题。

C++11
std::hash
类型能否用于散列函数指针?有一个
散列
部分专门化定义为

template <typename T> struct hash<T*>;
模板结构哈希;
<>但是由于函数指针与C++中的其他指针类型不同(例如,它们不能被转换成<代码> Value*/COD>),所以我不能确定它是否适合使用诸如“代码> int(*)())/>代码>或<代码>空洞(*)(int,int)< /> > < < 这是允许的吗?新的ISO规范中是否有支持或反驳这一点的具体措辞


谢谢

好问题。我不知道答案,我很乐意听从比我更了解的人,但我的想法是,即使函数指针与数据指针不同,它们仍然是指针:因此应该应用
std::hash
部分专业化

值得一提的是,即使在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;

}
#包括
#包括
void func1(int){}
void func2(int){}
int main()
{
typedef void(*func_type)(int);
std::散列;
我发现了以下几点:

17.6.3.4散列要求 类型H满足哈希要求,如果:

  • 它是一种函数对象类型(20.8)
[……]

然后,参考的20.8规定:

函数对象类型是对象类型(3.9),可以是 函数调用中的后缀表达式(5.2.2,13.3.1.1)。228 a 函数对象是函数对象类型的对象 人们希望将指向函数的指针传递给 算法模板(第25条),指定接口接受 一个函数对象。这不仅使算法模板与 指向函数的指针,但也使它们能够使用任意 函数对象


它有点倒着说……但这句话不仅使算法模板与函数指针一起工作……似乎适合你的问题。

这实际上很有趣……我在使用MSVC++时遇到了这个问题。我想做的是:

static std::unordered_map<Fun, std::string> FunctionMap()
{
    static std::unordered_map<Fun, std::string> map;
    return map;
}
在上一次尝试中,我尝试将函数指针强制转换为
void*
,这是不允许的,也不可编译(请参阅:了解详细信息)。原因是void*是数据指针,而函数指针是代码指针


到目前为止,我的结论是,它是不允许的,并且不会在MSVC++上编译。

这仅仅是理论上的吗?我认为函数指针的默认哈希函数没有任何实际用途,因为(在大多数实现中)它只是对指针下面的整数进行散列。@C.R.-这部分是理论上的,不过我也很好奇你是否可以制作一个类似于
std::unordered_map
的东西,它可以是从字符串到函数或类似的东西的逆映射。我在这里做了一些测试,我看到函数指针成功地转换为
void*@MuriloVasconcelos对于您的特定实现,是的。但是标准没有提供任何保证。@JonathanWakely:我错了。我认为好的散列必须将相关输入映射到看似随机的输出,但忘记了最终目的是避免冲突。智能指针肯定包含在标准中([util.smartptr.hash]20.7.2.6)。仍在查看代码指针是否正确。标准中没有说明
hash
不适用于任何指针类型,因此它确实适用。具体而言,它适用于任何“指向
void
的指针”或给定类型的对象或函数(包括类的静态成员)([basic.component]中给出的不同类型的指针)这个问题不涉及任何非类型模板参数。
T
是一个类型参数。@AndreyT Mhhh…我不是误读了标准,就是误解了标准…注意解释一下吗?这很简单。模板参数有三种:#1)类型参数,例如
template…
,#2)非类型参数,例如.
template…
,#3)模板参数,例如
template…
。在本例中,我们处理的是一个普通类型参数(#1)。同时,您提供了一个特别适用于非类型参数(#2)的报价.所以,我看不出你的报价在这里有什么关系。谢谢。我会相应地修改。这一段不是关于(一些虚构的)
Hashable
,而是关于
Hash
。它定义了哪些类型可以用来散列,而不是哪些类型可以散列。OP询问
std::Hash
(满足
散列
要求)可用于散列函数指针;如果函数指针满足
散列
要求,则不能使用。这与此无关。成员函数指针根本不是函数指针。
error C2338: The C++ Standard doesn't provide a hash for this type.
....
_Kty=int (__thiscall Testje::* )(int,int)