Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   How to pass function pointer by reference? (http://www.velocityreviews.com/forums/t685802-how-to-pass-function-pointer-by-reference.html)

Immortal Nephi 05-27-2009 10:32 PM

How to pass function pointer by reference?
 
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;
}

Immortal Nephi 05-28-2009 02:09 AM

Re: How to pass function pointer by reference?
 
On May 27, 6:25*pm, Stuart Golodetz
<sgolod...@NdOiSaPlA.pMiPpLeExA.ScEom> wrote:
> Immortal Nephi wrote:
> > * *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
> > * *}

>
> 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

>
> 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 -



SG 05-28-2009 08:56 AM

Re: How to pass function pointer by reference?
 
On 28 Mai, 04:09, Immortal Nephi wrote:
> [...]*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


All times are GMT. The time now is 10:25 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.