如何散列和比较指向成员函数的指针?
我如何散列(std::tr1::hash 或 boost::hash)一个 C++ 成员函数指针?
How can i hash (std::tr1::hash or boost::hash) a c++ pointer-to-member-function?
示例:
我有几个 bool (Class::*functionPointer)()(非静态)指向类 Class 的几个不同方法,我需要散列那些指向成员函数的指针.
I have several bool (Class::*functionPointer)() (not static) that point to several diferent methods of the class Class and i need to hash those pointer-to-member-function.
我该怎么做?
另外,我如何比较(std::less)那些成员函数指针,以便将它们存储在 std::set 中?
Also how can i compare (std::less) those member function pointers so i can store them in a std::set?
推荐答案
所有 C++ 对象,包括指向成员函数的指针,都在内存中表示为字符数组.所以你可以试试:
All C++ objects, including pointers to member functions, are represented in memory as an array of chars. So you could try:
bool (Class::*fn_ptr)() = &Class::whatever;
const char *ptrptr = static_cast<const char*>(static_cast<const void*>(&fn_ptr));
现在将 ptrptr
视为指向 (sizeof(bool (Class::*)()))
字节的数组,并散列或比较这些字节.如果您愿意,您可以使用 unsigned char
而不是 char
.
Now treat ptrptr
as pointing to an array of (sizeof(bool (Class::*)()))
bytes, and hash or compare those bytes. You can use unsigned char
instead of char
if you prefer.
这保证没有误报 - 在 C++03 中,指向成员函数的指针是 POD,这意味着它们可以使用 memcpy 进行复制.这意味着如果具有相同的字节对字节值,那么它们是相同的.
This guarantees no false positives - in C++03, pointers to member functions are POD, which means among other things that they can be copied using memcpy. This implies that if have the same byte-for-byte values, then they are the same.
问题在于成员函数指针的存储表示可能包括不参与值的位 - 因此对于指向同一成员函数的不同指针,它们不一定相同.或者编译器可能出于某种晦涩的原因,有不止一种方式指向同一个类的同一个函数,它们在字节上是不相等的.无论哪种方式,您都可能得到假阴性.您必须研究成员函数指针在您的实现中的实际工作方式.它必须以某种方式为成员函数指针实现operator==
,如果你能找出方法,那么你可能会找出一个顺序和一个散列函数.
The problem is that the storage representation of member function pointers could include bits which do not participate in the value - so they will not necessarily be the same for different pointers to the same member function. Or the compiler might, for some obscure reason, have more than one way of pointing to the same function of the same class, which are not byte-wise equal. Either way you can get false negatives. You'll have to look into how member function pointers actually work on your implementation. It must implement operator==
for member function pointers somehow, and if you can find out how then you can probably figure out an order and a hash function.
这可能很难:成员函数指针很笨拙,并且根据指向的函数类型(虚拟的、继承的),存储可能包含不同数量的非参与松弛空间".因此,您可能必须与编译器的实现细节进行大量交互.本文可能会帮助您入门:http://www.codeproject.com/KB/cpp/FastDelegate.aspx
That's potentially hard: member function pointers are awkward, and the storage is likely to include different amounts of non-participating "slack space" according to what kind of function is pointed to (virtual, inherited). So you'll probably have to interact quite significantly with your compiler's implementation details. This article might help get you started: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
更简洁的替代方法可能是对数组进行线性搜索,以便规范化"所有函数指针,然后根据数组中该函数指针的规范"实例的位置进行比较和散列.取决于您的性能要求是什么.并且即使有要求,类(及其派生类)的功能是否如此之多以至于线性搜索需要那么长时间?
A cleaner alternative might be to do a linear search through an array in order to "canonicalise" all your function pointers, then compare and hash based on the position of the "canonical" instance of that function pointer in your array. Depends what your performance requirements are. And even if there are requirements, does the class (and its derived classes) have so many functions that the linear search will take that long?
typedef bool (Class::*func)();
vector<func> canon;
size_t getIndexOf(func fn_ptr) {
vector<func>::iterator it = find(canon.begin(), canon.end(), fn_ptr);
if (it != canon.end()) return it - canon.begin();
canon.push_back(func);
return canon.size() - 1;
}
相关文章