I could be totally wrong here, but as I understand it, C++ doesn't really have a native "pointer to member function" type. I know you can do tricks with Boost and mem_fun etc. But why did the designers of C++ decide not to have a 64-bit pointer containing a pointer to the function and a pointer to the object, for example?
What I mean specifically is a pointer to a member function of a particular object of unknown type. I.E. something you can use for a callback. This would be a type which contains two values. The first value being a pointer to the function, and the second value being a pointer to the specific instance of the object.
What I do not mean is a pointer to a general member function of a class. E.G.
int (Fred::*)(char,float)
It would have been so useful and made my life easier.
Hugo
@RocketMagnet - This is in response to your other question, the one which was labeled a duplicate. I'm answering that question, not this one.
In general, C++ pointer to member functions can't portably be cast across the class hierarchy. That said you can often get away with it. For instance:
#include <iostream>
using std::cout;
class A { public: int x; };
class B { public: int y; };
class C : public B, public A { public: void foo(){ cout << "a.x == " << x << "\n";}};
int main() {
typedef void (A::*pmf_t)();
C c; c.x = 42; c.y = -1;
pmf_t mf = static_cast<pmf_t>(&C::foo);
(c.*mf)();
}
Compile this code, and the compiler rightly complains:
$ cl /EHsc /Zi /nologo pmf.cpp
pmf.cpp
pmf.cpp(15) : warning C4407: cast between different pointer to member representations, compiler may generate incorrect code
$
So to answer "why doesn't C++ have a pointer-to-member-function-on-void-class?" is that this imaginary base-class-of-everything has no members, so there's no value you could safely assign to it! "void (C::)()" and "void (void::)()" are mutually incompatible types.
Now, I bet you're thinking "wait, i've cast member-function-pointers just fine before!" Yes, you may have, using reinterpret_cast and single inheritance. This is in the same category of other reinterpret casts:
#include <iostream>
using std::cout;
class A { public: int x; };
class B { public: int y; };
class C : public B, public A { public: void foo(){ cout << "a.x == " << x << "\n";}};
class D { public: int z; };
int main() {
C c; c.x = 42; c.y = -1;
// this will print -1
D& d = reinterpret_cast<D&>(c);
cout << "d.z == " << d.z << "\n";
}
So if void (void::*)()
did exist, but there is nothing you could safely/portably assign to it.
Traditionally, you use functions of signature void (*)(void*)
anywhere you'd thing of using void (void::*)()
, because while member-function-pointers don't cast well up and down the inheritance heirarchy, void pointers do cast well. Instead:
#include <iostream>
using std::cout;
class A { public: int x; };
class B { public: int y; };
class C : public B, public A { public: void foo(){ cout << "a.x == " << x << "\n";}};
void do_foo(void* ptrToC){
C* c = static_cast<C*>(ptrToC);
c->foo();
}
int main() {
typedef void (*pf_t)(void*);
C c; c.x = 42; c.y = -1;
pf_t f = do_foo;
f(&c);
}
So to your question. Why doesn't C++ support this sort of casting. Pointer-to-member-function types already have to deal with virtual vs non-virtual base classes, and virtual vs non-virtual member functions, all in the same type, inflating them to 4*sizeof(void*) on some platforms. I think because it would further complicate the implementation of pointer-to-member-function, and raw function pointers already solve this problem so well.
Like others have commented, C++ gives library writers enough tools to get this done, and then 'normal' programmers like you and me should use those libraries instead of sweating these details.
EDIT: marked community wiki. Please only edit to include relevant references to the C++ standard, and add in italic. (esp. add references to standard where my understanding was wrong! ^_^ )