2016-04-25 35 views
8

作为哈希的一部分,我需要将函数指针转换为字符串表示形式。随着全球/静态函数是微不足道:如何获取成员函数的字符串表示形式?

string s1{ to_string(reinterpret_cast<uintptr_t>(&global)) }; 

而且从here

2)任何指针可以转换为任何整数类型足够大,以 将指针(如以std::uintptr_t值)

但我有一个问题,成员函数:

cout << &MyStruct::member; 

输出1虽然在调试器中我可以看到地址。

string s{ to_string(reinterpret_cast<uintptr_t>(&MyStruct::member)) }; 

给出一个编译时错误cannot convert。所以似乎没有任何指针可以转换。

我还能做些什么来获得字符串表示?

+0

'1'很可能是正确的值。毕竟,成员函数指针是相对的。这也意味着如果你不添加额外的信息,比如类型自身的typeid的散列,你可能会遇到很多冲突。当你说*没有任何指针可以被转换*时,请记住成员函数指针*不是*指针;他们正是*成员函数指针*。 –

+1

“所以看起来没有任何指针可以被转换......”指针与指向成员的指针不同,指针可以转换为整型,指向成员的指针不能。 – user657267

+5

指针到成员没有'operator <<'。 '&MyStruct :: member'是一个非空的指向成员的指针。任何指针都可以隐式转换为“bool”。非空指针转换为'true',默认打印为'1'。 – molbdnilo

回答

4
cout << &MyStruct::member; 

输出1虽然在调试器可以看我的地址。

ostream::operator<<(decltype(&MyStruct::member))没有超载。但是,成员函数指针可以隐式转换为bool,为此,存在重载并且这是重载解析的最佳匹配。如果指针不为空,转换后的值为truetrue输出为1


string s{ to_string(reinterpret_cast<uintptr_t>(&MyStruct::member)) }; 

给出一个编译时错误不能转换。所以似乎没有任何指针可以转换。

或许令人混淆,在standardese 指针不是对象指针的总称,指针到成员,指针到功能和指针到成员函数。指针特指数据指针。

所以,引用的规则不适用于指向成员函数的指针。它只适用于(对象)指针。


还有什么我能做得到的字符串表示?

您可以使用unsigned char缓冲区,大到足以代表指针,并使用std::memcpy。然后以您自己选择的格式打印。我推荐十六进制。

正如Martin Bonner指出的那样,指向成员的指针可能包含填充,在这种情况下,指向同一成员的两个值实际上可能在缓冲区中具有不同的值。因此,打印值没有多大用处,因为如果不知道哪些位(如果有的话)是填充(padding) - 这是实现定义的,则两个值不具有可比性。


不幸的是,我需要一个强大的解决方案,因为这样可以填充我不能使用。

便携式存在健壮的解决方案。

正如Jonathan Wakely指出的那样,Itanium ABI中没有填充,所以如果你的编译器使用它,那么建议的memcpy方法就可以工作。

+0

存在*指针指向的成员*的某些数据被忽略填充空间的风险。在这种情况下,包含指向同一成员的指针的不同变量可能具有不同的填充值 - 并以十六进制打印出来(不正确)会产生不同的散列值。我不确定这是否是一个无需编译器支持即可解决的问题(一般情况下)。 (当然在实践中,你的建议可能会起作用。) –

+0

@MartinBonner好点。我没有考虑过nikitablack可能使用的字符串表示方式。 – user2079303

+0

谢谢。不幸的是,我需要一个强大的解决方案,因为这个填充我不能使用。而且,我不知道如何复制它。 'memcpy'接受'void *'作为源,但*指向成员*不能转换为它。 – nikitablack

相关问题