简体   繁体   English

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

[英]Can std::hash be used to hash function pointers?

Can the C++11 std::hash type be used to hash function pointers? 可以使用C ++ 11 std::hash类型来散列函数指针吗? There is a hash partial specialization defined as hash部分特化定义为

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

but since function pointers are different from other pointer types in C++ (eg they can't be cast to void* ), I'm not sure whether it is safe to use it for types like int(*)() or void(*)(int, int) . 但由于函数指针与C ++中的其他指针类型不同(例如它们不能转换为void* ),我不确定将它用于int(*)()void(*)(int, int)等类型是否安全void(*)(int, int)

Is this permitted? 这是允许的吗? Is there any specific wording in the new ISO spec that supports or refutes this? 新的ISO规范中是否有任何特定的措辞支持或驳斥这一点?

Thanks! 谢谢!

Great question. 好问题。 I don't know the answer for sure, and I'm happy to defer to anyone with better knowledge than me, but my thinking is that even though function pointers aren't the same as data pointers, they are pointers nonetheless: so the std::hash<T*> partial specialisation should be applied. 我肯定不知道答案,我很乐意推荐给比我更有知识的人,但我的想法是,即使函数指针与数据指针不同,它们仍然是指针:所以应该应用std::hash<T*>部分特化。

For what it's worth, the following compiles without warnings even with -pendantic in g++ 4.8.1 and clang 3.3, and works as expected: 对于它的价值,以下编译没有警告,即使在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;

}

I'd be really interested if anyone has any references to the standard to back this up though. 我真的很感兴趣,如果有人有任何参考标准来支持这一点。

I found the following: 我找到了以下内容:

17.6.3.4 Hash requirements 17.6.3.4哈希要求

A type H meets the Hash requirements if: 如果出现以下情况,H类型符合Hash要求:

  • it is a function object type (20.8) 它是一个函数对象类型(20.8)

[...] [...]

And then, the referenced 20.8 states: 然后,引用的20.8状态:

A function object type is an object type (3.9) that can be the type of the postfix-expression in a function call (5.2.2, 13.3.1.1).228 A function object is an object of a function object type. 函数对象类型是对象类型(3.9),它可以是函数调用中的postfix-expression的类型(5.2.2,13.3.1.1).228函数对象是函数对象类型的对象。 In the places where one would expect to pass a pointer to a function to an algorithmic template (Clause 25), the interface is specified to accept a function object. 在人们期望将指向函数的指针传递给算法模板的地方(第25条),接口被指定为接受函数对象。 This not only makes algorithmic templates work with pointers to functions, but also enables them to work with arbitrary function objects. 这不仅使算法模板与函数指针一起使用,而且使它们能够使用任意函数对象。

It kind of states it backwards... but the statement not only makes algorithmic templates work with pointers to functions... seems appropriate for your question. 它有点向后陈述......但声明不仅使算法模板与函数指针一起工作......似乎适合你的问题。

It's actually interesting... I bumped into this question while using MSVC++. 这真的很有趣......我在使用MSVC ++时碰到了这个问题。 What I'm trying to do is: 我想要做的是:

static std::unordered_map<Fun, std::string> FunctionMap()
{
    static std::unordered_map<Fun, std::string> map;
    return map;
}

with Fun a function pointer type. 用Fun函数指针类型。

During compilation, I get the following error: 在编译期间,我收到以下错误:

error C2338: The C++ Standard doesn't provide a hash for this type.
....
_Kty=int (__thiscall Testje::* )(int,int)

In a previous attempt I attempted to cast the function pointer to void* , which isn't allowed and doesn't compile (see: https://isocpp.org/wiki/faq/pointers-to-members#cant-cvt-memfnptr-to-voidptr for details). 在之前的尝试中,我尝试将函数指针强制转换为void* ,这是不允许的,也不会编译(请参阅: https//isocpp.org/wiki/faq/pointers-to-members#cant-cvt- memfnptr-to-voidptr了解详情)。 The reason is that a void* is a data pointer, while a function pointer is a code pointer. 原因是void *是数据指针,而函数指针是代码指针。

My conclusion so far is that it isn't allowed and it won't compile on MSVC++. 到目前为止我的结论是它是不允许的,它不会在MSVC ++上编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM