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

时间:2013-11-01 02:54:10

标签: c++ pointers c++11 hash stdhash

可以使用C ++ 11 std::hash类型来散列函数指针吗? hash部分特化定义为

template <typename T> struct hash<T*>;

但由于函数指针与C ++中的其他指针类型不同(例如,它们不能转换为void*),我不确定将它用于类似int(*)()的类型是否安全}或void(*)(int, int)

这是允许的吗?新的ISO规范中是否有任何特定的措辞支持或反驳这一点?

谢谢!

3 个答案:

答案 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 ++上编译。