How to pass function pointer by reference?

I

Immortal Nephi

I need to pass function pointer by reference because it invokes first
function and then invokes second function with the same parameter.
How can I fix it?

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;
}
 
I

Immortal Nephi

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
        }

};

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
 
S

SG

[...] 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.

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top