Converting class function pointer to void* or vice

2019-09-03 07:25发布

问题:

Im trying to compare the address of two functions for equality. Type of my stored function is known. This system normally works, consider the following code (written as sample not from the program):

virtual bool compare(void *fn2) {
  void (*fn)(int);

  if(fn==fn2)
     return true;
}

However when class functions came into consideration the same method doesn't work.

virtual bool compare(void *fn2) {
  void(__thiscall myclass::*fn)(int);
  void *fn2;

  if(fn==fn2)  //error C2440 type cast: cannot convert void* to void(__thiscall...
     return true;
}

These functions override a common base class' pure virtual function similar to following:

virtual bool compare(void*) = 0;

Since I cannot use template<> in virtual functions I am out of options. Is there a way (anyway) to unify class functions and regular functions?

Thanks in advance, Cem

回答1:

Posix requires the ability to convert function pointers to void*. Standard C++ does not support it.

Member function pointers are not pointers in the ordinary sense, they're more like offsets (even for a non-virtual member function).

Both implementations you show for compare would have Undefined Behavior even if the comparisions and casts were valid, because they fail to return anything in the case where the pointers don't compare equal. Instead of if(blah == bag){ return true; } just do return (blah == bah);.

The problems stem from casting away necessary type information. That's generally not a good idea. Why are you casting away the type information that you need?

Solution: (1) don't cast away necessary type information, and (2) redesign to get rid of that compare function. Also take note of Roger Pate's comment that it seems you're asking about a particular attempted solution rather then the problem. What is the problem?

Cheers & hth.,



回答2:

This doesn't work because member function pointers are not actually convertible to regular pointers- their size is undefined. In some implementations of some class hierarchies, the member function pointer can be five times the size of a regular pointer. How is this going to work with a comparison to void*?