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. The printf_print does not compile because p cannot be casted to 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.
Let me know if you have any doubts.
To print the address of a variable, we use "%p" specifier in C programming language. There are two ways to get the address of the variable: By using "address of" (&) operator. By using pointer variable.
There's no standard format specifier to print a function pointer. %p is only for data pointer, not for a function pointer. So to print a function pointer using %p is undefined behaviour. This works because converting any object to a character pointer is allowed ( char* , unsigned char* or signed char* ).
We can get the address of a function by just writing the function's name without parentheses. Please refer function pointer in C for details. In C/C++, name of a function can be used to find address of function.
The line printf(“%d”,i) use the format specifier %d to print integers. In the next line %p is used to print addresses or pointer types in C.
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 *)
. Forcefully casting it to void *
will in any case discard a portion of the pointer representation, thus no longer guaranteeing the uniqueness.
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:
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...
Presumably some macro might help to make it simpler.
Hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With