If I got it correct, you did this:
class SomeClass
{
public:
double OptimizeCallback(double*) { /* ... */ }
};
typedef double (SomeClass::*Pstd_mem)( double* pv );
// somewhere in the code
Pstd_mem p = &SomeClass::OptimizeCallback;
optimise(p);
As previous 3 posters replied, there is a distinction between a
non-member function and a member function. The distinction is that
latter one needs an additional "this" pointer (something like, "mov
ecx, this", in x86 assembly). In C++, there is no (standard and
reliable) way to know, at compile time, where the function is going to
be located.
Valentin's answers are cool. I'm not keen with libraries, and I didn't
know whether boost has such a thing. But in that case, you need to use
boost, and probably you'll need to ship boost libary (.so or .dll)
along with your binary.
There ways, arguably efficient and reliable, but they are compiler and
platform dependent. If you don't have a portability concern, I think we
can solve this problem. But again, these ways are not supported by
standard, so generated executable may not run properly, next time you
compile it with newer version of your current compiler.
What I thought, for example, is first defining an "interface", which
could be thought as a "struct of function pointers" in C, derive
classes from this interface, write a template adapter class that
returns pointer to the member function (forcibly and tricky, through
vtable offset), pass this pointer to optimise() as if it is the double
(funk*)(double*). Since standard doesn't define vtable layout, the code
won't be portable, and it may need some more tailoring, if your classes
have different inheritance model (multiple, virtual, etc). As Valentin
pointed out, this may become difficult to implement for more complex
scenarios. Again, I want to point out that I am not really sure how
safe it is! Test good and ask your compiler vendor, if you intend to
use this:
For Visual C++: (I guess it works as of VC++ 6.0)
typedef double(*PFUNK)(double*);
void optimise(PFUNK pf)
{
double d = 3.0;
pf(&d);
}
// Interface definition
struct IOptimizable
{
virtual double OptimizeCallback(double* p) = 0;
};
// your class will derive from IOptimizable interface
class SomeClass : public IOptimizable
{
public:
virtual double OptimizeCallback(double* pdbl)
{
cout << *pdbl << endl;
return *pdbl;
}
};
// adapter class, returns a pointer to the member function.
template<class T>
class OptimizeAdapter
{
const T* m_pt;
public:
explicit OptimizeAdapter(const T* pt)
:m_pt(pt)
{
}
operator PFUNK()
{
IOptimizable const* popt = static_cast<IOptimizable
const*>(m_pt);
void* pvtbl = ((void**)popt)[0]; // vtable is at offset 0
return (PFUNK)((void**)pvtbl)[0]; // one-and-the-only function
is at offset 0
}
};
int main()
{
SomeClass r;
OptimizeAdapter<SomeClass> adapt(&r);
optimise(adapt);
return 0;
}
One more point; the object of type SomeClass should live until
optimise() returns. Otherwise, all bets are off (undefined), as far as
I know.
I used an adapter class, because you may need further additions and
fine tuning before returning function pointer.
Please let me know, if you intend to use and whether it works :)
Ismail
[ See
http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]