How to print method pointer address 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 clearly not what I want. Printf_print does not compile because p cannot be sent to void *.

I need a unique method pointer identifier that I can store in the container. I know this sounds good, but I am developing a small unit testing toy that can benefit from it. I'm not worried about method overloads; I know how to get a pointer to a specific overload.

I am using g ++ 4.4.3 with C ++ 0x enabled.

Let me know if you have any doubts.

+7
source share
4 answers

A function-function pointer is usually an object with a nontrivial internal structure. This is why you cannot print it with tools designed to print primitive types. Hovering over void * not a viable approach since the size of the member pointer is usually larger than sizeof(void *) . Forcibly casting it to void * , in any case, will throw away part of the pointer representation, thereby no longer guaranteeing uniqueness.

If what you are looking for is a unique string created with a pointer, you can re-interpret the pointer as an array of characters and use the string representation of the 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"); 
+9
source

Although I'm not 100% sure, I correctly understand the question, if there is some kind of mapping from the member pointer to some unique identifier, the following code can fulfill the goal:

 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 to get_unique_id bit long, though ... Presumably some macros may help make this easier.

Hope this helps

+4
source

If you only need to work with GCC, you can use this extension to extract a function pointer from a pointer to a member function.

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.

+1
source

There is no portable way to do this. But have you tried reinterpret_cast<void*>(p) ?

I suspect stream_print uses std::operator<<(std::ostream&, bool) , as this is the only valid conversion for a member-pointer type. This explains why you get 1 .

I would not expect printf_print to work even if the compiler allowed to pass a member pointer function through ... There is no guarantee of sizeof(p) == sizeof(void*) , which is often a practical minimum for obtaining "expected" non-standard results from va_arg .

0
source

All Articles