[英]How do I print the address of a method pointer in C++?
For example: 例如:
struct A { void m() { } };
void stream_print() {
void(A::*p)(void) = &A::m;
std::cerr << p << std::endl;
}
void printf_print() {
void(A::*p)(void) = &A::m;
fprintf(stderr, "%p", p);
}
The stream_print() function always prints "1", which is obviously not what I want. stream_print()函数总是打印“1”,这显然不是我想要的。 The printf_print does not compile because p cannot be casted to void*.
printf_print无法编译,因为p无法转换为void *。
What I need is a unique identifier for a method pointer that I can store in a container. 我需要的是一个方法指针的唯一标识符,我可以存储在容器中。 I know this sounds like a bad idea, but I am developing a small toy for unit testing that can benefit from it.
我知道这听起来不错,但我正在开发一种可以从中受益的单元测试小玩具。 I am not worried about overloads of the method, I know how to get the pointer to a specific overload.
我不担心方法的重载,我知道如何获得指向特定重载的指针。
I am using g++ 4.4.3 with C++0x enabled. 我正在使用启用了C ++ 0x的g ++ 4.4.3。
Let me know if you have any doubts. 如果您有任何疑问,请告诉我。
Member function pointer is generally an object with non-trivial internal structure. 成员函数指针通常是具有非平凡内部结构的对象。 Which is why you can't print it using tools intended for printing primitive types.
这就是为什么你不能使用打印原始类型的工具打印它。 Casting the pointer to
void *
is not a viable approach, since the size of member pointer is generally larger than sizeof(void *)
. 将指针强制转换为
void *
不是一种可行的方法,因为成员指针的大小通常大于sizeof(void *)
。 Forcefully casting it to void *
will in any case discard a portion of the pointer representation, thus no longer guaranteeing the uniqueness. 强制将其强制转换为
void *
将在任何情况下丢弃指针表示的一部分,从而不再保证唯一性。
If what you are looking for is a unique string generated from the pointer, you can reinterpret the pointer as a character array, and use the string representation of character values in the identifier. 如果您要查找的是从指针生成的唯一字符串,则可以将指针重新解释为字符数组,并使用标识符中字符值的字符串表示形式。 Something like
就像是
void (A::*p)(void) = &A::m;
for (size_t i = 0; i < sizeof p; ++i)
printf("%d ", reinterpret_cast<char *>(&p)[i]);
printf("\n");
Though I'm not 100% sure I understand the question correctly, if some mapping from a member pointer to some unique id is needed, the following code might meet the purpose: 虽然我不是100%确定我正确理解了这个问题,但如果需要从成员指针到某个唯一ID的映射,则以下代码可能符合以下目的:
struct A {
void f() {}
void g( int ) {}
};
template< class T, T >
char* get_unique_id() {
static char dummy;
return &dummy;
}
int main() {
set< char* > s;
s.insert( get_unique_id< decltype( &A::f ), &A::f >() );
s.insert( get_unique_id< decltype( &A::g ), &A::g >() );
s.insert( get_unique_id< decltype( &A::f ), &A::f >() );
s.insert( get_unique_id< decltype( &A::g ), &A::g >() );
cout<< s.size() <<endl; // prints 2
}
The call of get_unique_id
is a little lengthy though... get_unique_id
的调用虽然有点冗长......
Presumably some macro might help to make it simpler. 据推测,一些宏可能有助于使其更简单。
Hope this helps 希望这可以帮助
If it only needs to work with GCC, you could use this extension to extract a function pointer from a pointer to member function. 如果只需要使用GCC,则可以使用此扩展从指向成员函数的指针中提取函数指针。
Here is an example: 这是一个例子:
#include <iostream>
#include <stdio.h>
struct A { void m() { } };
typedef void (*mptr)(A*);
int main()
{
mptr p = (mptr)(&A::m);
std::cerr << (void*)p << std::endl;
fprintf(stderr, "%p\n", p);
}
Compile with -Wno-pmf-conversions
to suppress the warning. 使用
-Wno-pmf-conversions
进行编译以抑制警告。
There is no portable way to do this. 没有可移植的方法来做到这一点。 But have you tried
reinterpret_cast<void*>(p)
? 但你试过
reinterpret_cast<void*>(p)
吗?
I suspect stream_print
is using std::operator<<(std::ostream&, bool)
, since that's the only valid conversion for a pointer-to-member type. 我怀疑
stream_print
正在使用std::operator<<(std::ostream&, bool)
,因为这是指针到成员类型的唯一有效转换。 That would explain why you get 1
. 这可以解释为什么你得到
1
。
I wouldn't expect printf_print
to work, even if a compiler did allow passing a pointer-to-member-function through ...
. 我不希望
printf_print
工作,即使编译器也允许指针传递到成员函数通过...
。 There's no guarantee sizeof(p) == sizeof(void*)
, which is often a practical minimum for getting "expected" non-standard results from va_arg
. 没有保证
sizeof(p) == sizeof(void*)
,这通常是从va_arg
获得“预期的”非标准结果的实际最小值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.