如何获取成员函数的字符串表示?

nik*_*ack 8 c++ casting function-pointers

作为散列的一部分,我需要将函数指针转换为字符串表示.使用全局/静态函数,它是微不足道的:

string s1{ to_string(reinterpret_cast<uintptr_t>(&global)) };
Run Code Online (Sandbox Code Playgroud)

这里:

2)任何指针都可以转换为足够大的任何整数类型来保存指针的值(例如std::uintptr_t)

但我的成员函数有问题:

cout << &MyStruct::member;
Run Code Online (Sandbox Code Playgroud)

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

string s{ to_string(reinterpret_cast<uintptr_t>(&MyStruct::member)) };
Run Code Online (Sandbox Code Playgroud)

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

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

eer*_*ika 4

cout << &MyStruct::member;
Run Code Online (Sandbox Code Playgroud)

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

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


string s{ to_string(reinterpret_cast<uintptr_t>(&MyStruct::member)) };
Run Code Online (Sandbox Code Playgroud)

给出编译时错误,无法转换。所以看来不是任何指针都可以转换的。

也许令人困惑的是,在标准术语中,指针并不是对象指针、成员指针、函数指针和成员函数指针的总称。指针特指数据指针。

因此,引用的规则不适用于指向成员函数的指针。它仅适用于(对象)指针。


我还能做什么来获取字符串表示形式?

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

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


不幸的是,我需要一个强大的解决方案,因此由于这个填充,我无法使用。

不存在便携式、稳健的解决方案。

正如 Jonathan Wakely 指出的那样,Itanium ABI 中没有填充,因此如果您的编译器使用它,那么建议的 memcpy 方法将起作用。