class A
{
public:
A() : m_a( 5 ) {}
~A() {}
void Run( void (&rF)( const A &ra ) )
{
printf("Run\n");
rF( *this ); // OK
Go1( rF( *this ) ); // Error
}
void Go1( void (&rF)( const A &ra ) )
{
printf("Go1\n");
Go2( ? ); // Fix
}
void Go2( void (&rF)( const A &ra ) )
{
printf("Go2\n");
rF( *this ); // OK
}
};
void F1( const A &ra )
{
printf("Test: %d\n", ra.m_a );
}
int main()
{
A a;
a.Run( F1 );
return 0;
}
The expression rF(*this) has type void: you're trying to pass the
non-existent result of a function with void return type to a function
which takes a void (&)(const A&). Replace rF(*this) with rF and it works
fine:
#include <cstdio>
class A
{
public:
int m_a;
A() : m_a( 5 ) {}
void Run( void (&rF)( const A &ra ) )
{
printf("Run\n");
rF( *this ); // OK
Go1( rF);
}
void Go1( void (&rF)( const A &ra ) )
{
printf("Go1\n");
Go2( rF );
}
void Go2( void (&rF)( const A &ra ) )
{
printf("Go2\n");
rF( *this ); // OK
}
};
void F1( const A &ra )
{
printf("Test: %d\n", ra.m_a );
}
int main()
{
A a;
a.Run( F1 );
return 0;
}
Note that you also needed to add a member variable m_a.
Regards,
Stu
Thank you for the reply. It does work because F!() is global
function. What if you want to invoke member function like this below.
void B::F1( const A &ra )
void C::F1( const A &ra )
Pass Member Function by Reference will only work one object if
you use B object or C object.
> void Run( void (&rF)( const A &ra ) )
I am not sure how you can do this Run() function above. I
need to put B::F1 or C::F1 in a.Run( ?? ). C++ Compiler should
compile successfully if only one object is used however template
function is the answer to accept either B object or C object. I am
concerned. After you create static library or DLL library, C++
Compiler will fail to compile because it does not know which type in
template function.
Nephi
>
> void F1( const A &ra )
> {
> printf("Test: %d\n", ra.m_a );
>
> }
>
> int main()
> {
> A a;
> a.Run( F1 );
>
> return 0;
>
> }
>
> Note that you also needed to add a member variable m_a.
>
> Regards,
> Stu
>
>
>
>
>
> > void Go1( void (&rF)( const A &ra ) )
> > {
> > printf("Go1\n");
> > Go2( ? ); // Fix
> > }
>
> > void Go2( void (&rF)( const A &ra ) )
> > {
> > printf("Go2\n");
> > rF( *this ); // OK
> > }
> > };
>
> > void F1( const A &ra )
> > {
> > printf("Test: %d\n", ra.m_a );
> > }
>
> > int main()
> > {
> > A a;
> > a.Run( F1 );
>
> > return 0;
> > }- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -
This sounds familiar. Isn't it practically the same question you asked
in a previous thread? And didn't you already get an answer there?
You want to write non-templated function in your library that takes a
"call back" as parameter of some type that should support calling non-
static member functions of some bound object of various classes.
A type-safe variant is possible (via something like boost::function)
but you probably have to make sure that both, your library and the
client's code, is compiled with the same version of boost::function
(or whatever replacement you use). So, the binary interface is a bit
fragile.
The other option (the C way of doing this) would be to use a plain
function pointer in combination with a void pointer that stores some
user-defined address:
// non-templated library function
void run( void(*pf)(void*), void* context )
{
pf(context);
}
class C {
void f();
};
void invoke_C_f(void* ctx) {
static_cast<C*>(ctx)->f();
}
int main() {
C c;
run(&invoke_C_f,&c);
}
You just need to be careful with the pointer types. Here, C* is
converted implicitly to void* and back again to C* which is guaranteed
to be lossless. But the type information is lost with void* which is
why you can't rely on the conversion C* -> void* -> D* (where D is a
base class of C) to give you the same result as C* -> D*. The latter
conversion might include an automatic pointer adjustment.
Cheers!
SG