Newbie: Functor: how to pass it like c style function pointer.

Newbie: Functor: how to pass it like c style function pointer.

Post by Amit Bhati » Thu, 31 Jul 2003 17:18:30



Hello All!,
  I tried looking for the solution to my problem on C++ FAQ LITE (Sec 33),
and some more places, but could not figure out the solution.
  Here's my problem:
  I have defined a functor "F" as an abstract class, and then a template "T"
derived from it.
  Both of these have two methods that have some format(signature) that I need
for callback functions for some other class "C".
  Now I instantiate the template "T" (call it sTemp) in one of my methods of
class "C" using the class "C" itself as the class type, along with two of
its methods CM1 and CM2 with signatures as,

void C::CM1(int, double);
void C::Cm2(int , double, double);

and then I create a pointer to pointer to "F" (call it sFunct) and make it
point to the address of the above object.

(*sFunct) = &sTemp;

Now I simply try to pass the methods declared in "F" to create an object of
some other class "OC"(call it obj).

OC obj(int, &((*sFunct)->CM1),&((*sFunct)->CM2)) );

The constructor of the OC class is :

OC::OC(int, void (*)(int, double), void(*)(int, double, double) );

But the compiler simply refuses to accept these as valid call back functions
though their declarations are exactly the same as the constructor of "OC"
wants.
g++(version 3.2)  says:

warning: ISO C++ forbids taking the address of a bound member function to
form a pointer to member function.  Say `&F::CM1'

I realize that this is must be a pretty standard issue in C++ with pretty
standard solutions.
  I will greatly appreciate any help, pointers that may help.

Thanking you,
best regards,
amit.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Newbie: Functor: how to pass it like c style function pointer.

Post by Jens Kilia » Fri, 01 Aug 2003 09:03:53



> warning: ISO C++ forbids taking the address of a bound member function to
> form a pointer to member function.  Say `&F::CM1'

> I realize that this is must be a pretty standard issue in C++ with pretty
> standard solutions.

The standard solution is to do what the compiler so helpfully suggests :-)

But this actually won't help you, as the compiler will then reject your code
for trying to pass a pointer-to-member-function to a function which expects
a pointer-to-function.  You need to learn about the difference between the two.

The Boost 'function' library (which is expected to become part of the next
version of the C++ standard) may help.

Bye,
        Jens.
--

  http://www.bawue.de/~jjk/          fax:+49-7031-464-7351
                                   As the air to a bird, or the sea to a fish,
                                   so is contempt to the contemptible. [Blake]

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Newbie: Functor: how to pass it like c style function pointer.

Post by Ben Hutching » Fri, 01 Aug 2003 09:13:10



> Hello All!,
>   I tried looking for the solution to my problem on C++ FAQ LITE (Sec 33),
> and some more places, but could not figure out the solution.

That's odd - section 33 has all the answers.

Quote:>   Here's my problem:
>   I have defined a functor "F" as an abstract class, and then a template "T"
> derived from it.
>   Both of these have two methods that have some format(signature) that I need
> for callback functions for some other class "C".
>   Now I instantiate the template "T" (call it sTemp) in one of my methods of
> class "C" using the class "C" itself as the class type, along with two of
> its methods CM1 and CM2 with signatures as,

> void C::CM1(int, double);
> void C::Cm2(int , double, double);

> and then I create a pointer to pointer to "F" (call it sFunct) and make it
> point to the address of the above object.

> (*sFunct) = &sTemp;

> Now I simply try to pass the methods declared in "F" to create an object of
> some other class "OC"(call it obj).

> OC obj(int, &((*sFunct)->CM1),&((*sFunct)->CM2)) );

There are 2 obvious syntax errors in this code.  Please copy and paste in
future, rather than re-typing.

Quote:> The constructor of the OC class is :

> OC::OC(int, void (*)(int, double), void(*)(int, double, double) );

> But the compiler simply refuses to accept these as valid call back functions
> though their declarations are exactly the same as the constructor of "OC"
> wants.

No, they aren't.  Non-static member functions are always called on a
specific object, which means they have a different type (FAQ 33.1).

Quote:> g++(version 3.2)  says:

> warning: ISO C++ forbids taking the address of a bound member function to
> form a pointer to member function.  Say `&F::CM1'

It seems like you're trying to bind the member functions to objects, making
ordinary function pointers, but that's not possible.  The only correct
syntax for taking a pointer-to-non-static-member-function is, as it says,
&class-name::function-name (with an appropriate cast if the function name
is overloaded).

Quote:> I realize that this is must be a pretty standard issue in C++ with pretty
> standard solutions.
>   I will greatly appreciate any help, pointers that may help.

See FAQ 33.2.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Newbie: Functor: how to pass it like c style function pointer.

Post by llewell » Fri, 01 Aug 2003 09:14:22



> Hello All!,
>   I tried looking for the solution to my problem on C++ FAQ LITE (Sec 33),
> and some more places, but could not figure out the solution.
>   Here's my problem:
>   I have defined a functor "F" as an abstract class, and then a template "T"
> derived from it.
>   Both of these have two methods that have some format(signature) that I need
> for callback functions for some other class "C".
>   Now I instantiate the template "T" (call it sTemp) in one of my methods of
> class "C" using the class "C" itself as the class type, along with two of
> its methods CM1 and CM2 with signatures as,

Please post a short but complete code example, from which the error
    can be reproduced. English summaries are seldom adequate.

Quote:> void C::CM1(int, double);
> void C::Cm2(int , double, double);

> and then I create a pointer to pointer to "F" (call it sFunct) and make it
> point to the address of the above object.

> (*sFunct) = &sTemp;

> Now I simply try to pass the methods declared in "F" to create an object of
> some other class "OC"(call it obj).

> OC obj(int, &((*sFunct)->CM1),&((*sFunct)->CM2)) );

It is hard to tell, because you have not posted real code, but this
    seems wrong. If CM1 and CM2 are member functions, you cannot apply
    operator-> to them and take the address of the result. If you want
    the address of the member function, you must do so by the
    qualified name of the member function, e.g. '&F::CM2' .

Quote:> The constructor of the OC class is :

> OC::OC(int, void (*)(int, double), void(*)(int, double, double) );

> But the compiler simply refuses to accept these as valid call back functions
> though their declarations are exactly the same as the constructor of "OC"
> wants.
> g++(version 3.2)  says:

> warning: ISO C++ forbids taking the address of a bound member function to
> form a pointer to member function.  Say `&F::CM1'

[snip]

Most of the time, when you get this warning, you can do just as it
    says, and wirte '&F::CM1', and your problem will be fixed. However
    there are exceptions, but I cannot tell what that exception is
    unless you post real code.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Newbie: Functor: how to pass it like c style function pointer.

Post by David Bradle » Fri, 01 Aug 2003 21:39:28


 > warning: ISO C++ forbids taking the address of a bound member function to
 > form a pointer to member function.  Say `&F::CM1'

You probably want to use pointer to members. Find a good C++ book and
check the index, or this has some examples
http://www.cs.wustl.edu/~schmidt/PDF/C++-ptmf4.pdf

The alternative if you have no control over the code accepting the
callback is to create function wrappers that make the call for you. You
have to devise some way to get the object pointer known to the function
when it's called. And you also have to consider reentrancy and threading
issues.

David Bradley

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Newbie: Functor: how to pass it like c style function pointer.

Post by Amit Bhati » Fri, 01 Aug 2003 21:46:52


Thanks,
  I am sorry for posting text like code.
  I was not sure about one thing which I understand pretty clearly now: there
is no way of converting "pointer-to-member-function" to a
"pointer-to-function".
  I mistakenly understood that there would be a way around this problem using
functors.
  I am further constrained because of the following facts:

1. The fact that I am using a third party class for whose constructor I need
to pass pointers to functions having some specific signature.

2. I don't want to be using static declaration for the method that I wish to
pass to the third party constructor as a callback function(due to the fact
that static methods can access only access static data members).

  So if I am not mistaken, then, I suppose, that boost function library might
be of help in here by somehow using some elegant tricks' to do this task.
   (There is the fact also that every instance of my class has lot of data
which is different and I need access to the data for the method that I wish
to pass).

Am I right, or is there a more simple way than this?

(The next thing I would need to do would be to get some hold of the boost
function library usage !) ;)

thanking you,
best regards,
amit.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Newbie: Functor: how to pass it like c style function pointer.

Post by Ben Hutching » Sat, 02 Aug 2003 04:12:36



> Thanks,
>   I am sorry for posting text like code.
>   I was not sure about one thing which I understand pretty clearly now: there
> is no way of converting "pointer-to-member-function" to a
> "pointer-to-function".
>   I mistakenly understood that there would be a way around this problem using
> functors.
>   I am further constrained because of the following facts:

> 1. The fact that I am using a third party class for whose constructor I need
> to pass pointers to functions having some specific signature.

> 2. I don't want to be using static declaration for the method that I wish to
> pass to the third party constructor as a callback function(due to the fact
> that static methods can access only access static data members).

Yes, but one of those static data members can be a pointer to the object that
the callback function will use.  This kluge works as long as the function will
only need access to one object at a time.  If there can be multiple instances
of the third-party class that should each be associated with a separate
instance of your class, then it gets harder.  If there will only be one per
thread, you can use TLS rather than a static member.  If the callback function
is given a pointer to the instance of the third-party class, perhaps you can
use some kind of map between pointers to their objects and your objects?

Quote:>   So if I am not mistaken, then, I suppose, that boost function library might
> be of help in here by somehow using some elegant tricks' to do this task.

<snip>

I'm afraid not - it is useful for writing functions that will accept any
suitable type of function or functor as an argument, but it is not useful
for creating function pointers to pass to older interfaces.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Newbie: Functor: how to pass it like c style function pointer.

Post by Amit Bhati » Sat, 02 Aug 2003 10:08:13


David,
 Thanks. Will I be correct in saying that binding might help. Well the boost
library function does give some notes on how to do this using the function
library and the std::bind1st and std::mem_fun together one can bind the
object of a pointer-to-member function for use with Boost.Function. They
give one of the examples as something like:

boost::function<int (int)> f;
  X x;
  f = std::bind1st(std::mem_fun(&X::foo), &x);
  f(5); // Call x.foo(5)

So can I do this? I mean will the constructor of the third party class
accept this as a callback function? As you have rightly pointed out, I have
no control over the third party class to whose constructor I need to pass
the pointer to callback functions. So yes, I can't modify the constructor.
I don't want to be using static functions since for all the methods of my
class I need access to non static members.

best regards,
amit.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Newbie: Functor: how to pass it like c style function pointer.

Post by llewell » Sun, 03 Aug 2003 17:51:39


 > David,
 >  Thanks. Will I be correct in saying that binding might help. Well the boost
 > library function does give some notes on how to do this using the function
 > library and the std::bind1st and std::mem_fun together one can bind the
 > object of a pointer-to-member function for use with Boost.Function. They
 > give one of the examples as something like:
 >
 > boost::function<int (int)> f;
 >   X x;
 >   f = std::bind1st(std::mem_fun(&X::foo), &x);
 >   f(5); // Call x.foo(5)
 >
 > So can I do this? I mean will the constructor of the third party class
 > accept this as a callback function?

I think the answer is no. A functor is not a pointer to a function.

 > As you have rightly pointed out, I have
 > no control over the third party class to whose constructor I need to pass
 > the pointer to callback functions. So yes, I can't modify the constructor.
 > I don't want to be using static functions since for all the methods of my
 > class I need access to non static members.

Why don't you want to use:

class A
{
   public:

     static void callback(A* p);

Quote:};

?

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

Newbie: Functor: how to pass it like c style function pointer.

Post by Amit Bhati » Mon, 04 Aug 2003 11:07:11


Ok,
 Now, I am indeed defining a static method(Say C::CSM) as a wrapper for the
non static method (C::CM) and then a static pointer to the class itself
(static C *CP;)to use all member data of the particular instance of the
class(class is C).
 Now I have a  new doubt coming up:

I define protected Init() methods for all my classes which I use while
making calls to constructors etc. Now I am setting the value of this static
pointer =0 inside this method.
 i.e CP=0;
 And then when I call the static method, it calls the non static method
where in the beginning I set

void C::CM(arguement list)
 CP = this ;
//all the method work follows !
//call CSM(arguement list) somewhere in here !

 CP = 0; //resetting it to 0 again for safety !

So is this whole thing correct. Though the static members need to be set to
some value somewhere outside of the class but then ISO C++ forrbids setting
CP = 0 outside of class !
 It would allow setting this to some dummy/NULL type value obviously.... but
not 0 !

thanks,
regards,
amit.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

1. How to pass the object pointer and/or member function pointer to member object?

Hi, all.

I want to mimic the Delphi property feature and do following:

template< class T, class C>
class TProperty{
     public:
            TProperty( C * pt, T ( C::*rd)(),  void (C::*wt)( T ) );
             operator T(){ return  parent -> *Read() ;}
             void operator=( T t) { parent -> * Wrtie() ;}
protected:
     C * parent ;
     T (C::* Read)();
     void ( C::*Write)( T )();

class TMyTest{
    public:
         float ReadFloat( ) { return var ;}
           void WriteFloat( float f ){  var = f ;}
     private :
             float f ;

public:
        TProperty< float, TMyTest>     MyFloat( this,
&TMyTest::ReadFloat, &TMyTest::WriteFloat );

//
^^^er1^^^^^^^^^^^^^^er2^^^^^^^^^^^^^^^^^^

What I want to do is to simplify the coding, for example, if the above
code can pass the compiler, you can
directly write following code:
   float f ;
    TMyTest tt;
 f  = tt.MyFloat ;   // the compiler call ::ReadFloat to do internal
process.
  tt.MyFloat = 3.5 ; // do :: WriteFloat to do process.

You know, there is a lot of read/write member data operation, you don't
want to directly manipulate
that data member, because you need do other kinds house-keeping work.

The above declaration give me 2 errors:
1 . Can not use "this" in top level .
2. the  incomplete class TMyTest don't contain ReadFLoat and WriteFLoat
function.

I use gcc 2 under Redhat linux 6.0 , How could I get what I want to do?
( I already tried put the TProperty  outside TMyTest, It can
be compiled and works what I want.)

2. Help w/ MSN & Internet Exp.

3. functors and function pointer interchanging

4. Plz. Help! Using VB, Win 95 Ver C, and the Epson TM-U200D Printer

5. function object or pointer to function and coding style

6. Polls in FP

7. passing a function pointer as a parameter to a function call

8. Syncing HP568 to a MAC

9. Passing a Class Member Function to a C-style Routine

10. Passing vector data to/from C-style functions

11. Newbie-ish question on passing pointers

12. Newbie problem with include files (old style vs new style)

13. How to pass a pointer to a COM interface function using VBScript