Pointers to member functions? 
Author Message
 Pointers to member functions?

An a "C" program, I have these declarations:

void (* f)(int);        // pointer to a function that has 1 int arg and
                // returns void

void g(int);    // one such function.

I can do:
a.      f = g;  // assignment
b.      f(2);   // indirectly invoke g
c.      if( f == g ) // test equality

Now, in
class X {
void (X::* f)(int);     // analogous to above
void g(int);    // ditto

Quote:
}

I can do a and c above but not b.  MSFT VC++ says
        error C2064: term does not evaluate to a function
Compiler help says you're probably calling a non-function.

note that (*f)(2) doesn't work either!

How can I do this?

tnx, steve



Sun, 30 Jul 2000 03:00:00 GMT  
 Pointers to member functions?

I might be wrong, but it might have something to do with the hidden 'this'
parameter that's present in accessing non-static class members.  If you make
the member function static, it will probably work.  But then you need to
pass another parameter to point to the class to access any non-static
members.

something like...

class MyClass
{

  static void Foo(MyClass* pMyClass, int ...etc);
  void Foo2(int ...etc);
  int someVar;

Quote:
}

void MyClass::Foo(MyClass* pMyClass, int var1...etc)
{
    pMyClass->myVar = var1;
    pMyClass->Foo2(int...etc);
    etc.

Quote:
}

You will now be able to call Foo just as if it's a regular C function, as
per your first example, but also pass in the address of the class you want
the function to operate on.

Remember that a call to a C function simply needs the address of the
function, where a call to a C++ function needs the address to the function
(the function name), as well as a pointer the where the data members is
stored for the class (the hidden 'this' pointer).

Hope that helps...

Steven Schulze
Concord,  CA

Quote:

>An a "C" program, I have these declarations:

>void (* f)(int); // pointer to a function that has 1 int arg and
> // returns void

>void g(int); // one such function.

>I can do:
>a. f = g; // assignment
>b. f(2); // indirectly invoke g
>c. if( f == g ) // test equality

>Now, in
>class X {
>void (X::* f)(int); // analogous to above
>void g(int); // ditto
>}

>I can do a and c above but not b.  MSFT VC++ says
> error C2064: term does not evaluate to a function
>Compiler help says you're probably calling a non-function.

>note that (*f)(2) doesn't work either!

>How can I do this?

>tnx, steve



Sun, 30 Jul 2000 03:00:00 GMT  
 Pointers to member functions?

You have a couple of choices depending on whether or not you want the
function to be applied to a specific member of your class.

If the function doesn't apply to a specific member of your class, you can
declare the function static. Then you can take its address and use it as
you would expect.

void (*f)(int) = &X::g;

If the function will be applied to a particular instance of X, you can
declare a pointer to member of X.

void (X::*mf)(int) = &X::g;

In this case, to use the pointer you must identify the instance of X to
which the function should be applied.

X anX;

(anX.*mf)(2);

or
X *pX;

(pX->*mf)(2);

Good luck!
--
Leonard Lehew
leonard.lehew at fmr.com
leonard.lehew at worldnet.att.net



Quote:
> An a "C" program, I have these declarations:

> void (* f)(int);   // pointer to a function that has 1 int arg and
>            // returns void

> void g(int);       // one such function.

> I can do:
> a. f = g;  // assignment
> b. f(2);   // indirectly invoke g
> c. if( f == g ) // test equality

> Now, in
> class X {
> void (X::* f)(int);        // analogous to above
> void g(int);       // ditto
> }

> I can do a and c above but not b.  MSFT VC++ says
>    error C2064: term does not evaluate to a function
> Compiler help says you're probably calling a non-function.

> note that (*f)(2) doesn't work either!

> How can I do this?

> tnx, steve



Sun, 30 Jul 2000 03:00:00 GMT  
 Pointers to member functions?

Quote:

> An a "C" program, I have these declarations:

> [pointer to a member syntax discussion deleted.]

The other answers in this thread have answered the author's concerns. It
has been my experience that there are usually better ways than pointer to
member functions to select a function at run-time. Lets suppose we have
a set of 3 functions which need to be invoked depending on the situation.
In C pointer to member syntax is used
to cause a method to get selected at runtime, or for use in a callback
function.

Sure it gets the job done, but then the usage is often pretty unwieldly by
the user of the library.

In C++ we usually write classes to be used by others so we want to make
their life as easy as possible. Also
don't forget the plight of the maintenance programmers. To make their lives
easier, with a little more work you
can implement a scheme roughly along these lines. This is pretty crude, but
the idea is
to wrap the function as an object which derives from DoTheRightThing, and
the ctor of DoTheRightThing will
call the right function at runtime.

class DoTheRightThing
{
//This class picks the right method to call given the state of the
constructor. The constructor code
//still has the big ugly switch statment that checks the outer flag. If the
flag is true it searches for the
//right case and creates the appropriate object. I put the ctor at the
bottom of this note.
public:
 DoTheRightThing(int arg, bool outer=true);

 virtual void operator()(int arg)
 {
  doit(arg);
 }
 virtual void doit(int arg)
 {
  object->doit(arg);
 }
 virtual ~DoTheRightThing(){if(object)delete object;}
private:
 DoTheRightThing* object;

Quote:
};

//These are the function objects we will invoke depending on the
DoTheRightThing argument.
//They each invoke their own version of doit
class f : public DoTheRightThing
{
public:
 f(int arg) : DoTheRightThing(arg,false){}
 virtual void doit(int arg) {  std::cout <<"f was called with arg =
"<<arg<<std::endl; }
Quote:
};

class g : public DoTheRightThing
{
public:
 g(int arg) : DoTheRightThing(arg,false){}
 virtual void doit(int arg) {
  std::cout << "g was called with arg = "<<arg<<std::endl;
 }
Quote:
};

class h : public DoTheRightThing
{
public:
 h(int arg) : DoTheRightThing(arg,false){}
 virtual void doit(int arg) {
  std::cout << "h was called with arg = "<<arg<<std::endl;
 }

Quote:
};

int main(void)
{
 const int DO_F = 1;
 DoTheRightThing foo(DO_F);
 foo(1);

const int DO_G = 2;
 DoTheRightThing bar(DO_G);
 bar(10);

 const int DO_H = 3;
 DoTheRightThing foobar(DO_H);
 foobar(30);
 return 0;

Quote:
}

DoTheRightThing::DoTheRightThing(int arg, bool outer)
{
 object = NULL;
 if(outer)
 {
  switch(arg)
  {
  case 1:
   {
    object = new f(arg);
    break;
   }
  case 2:
   {
    object = new g(arg);
    break;
   }
  case 3:
   {
    object = new h(arg);
    break;
   }
  default:
   {
    std::cerr << "unexpected argument to DoTheRightThing"<<std::endl;
    break;
   }
  }//end switch
 }//end if
Quote:
}//end ctor



Sun, 30 Jul 2000 03:00:00 GMT  
 Pointers to member functions?



Quote:
>An a "C" program, I have these declarations:

>void (* f)(int);    // pointer to a function that has 1 int arg and
>            // returns void

>void g(int);        // one such function.

>I can do:
>a.  f = g;  // assignment
>b.  f(2);   // indirectly invoke g
>c.  if( f == g ) // test equality

>Now, in
>class X {
>void (X::* f)(int); // analogous to above
>void g(int);        // ditto
>}

>I can do a and c above but not b.  MSFT VC++ says
>    error C2064: term does not evaluate to a function
>Compiler help says you're probably calling a non-function.

>note that (*f)(2) doesn't work either!

>How can I do this?

>tnx, steve

You can only call a pointer to member function through an object. For
example, if you have a pointer to an X, p, you can say:

 (p->*f)(2);

Inside a member function of X, to invoke f on the current object, you
can say:

 (this->*f)(2);

Now this is kind of obscure. The only legal way to initialize your
pointer to member function is:

 void (X::*f)(int) = &X::g;

While non-member functions decay into function pointers, member
functions don't decay into pointers to members, and the standard
permits no other syntax for the RHS. In particular, it requires the
"&X::" bit, always, though compilers tend to be more lenient.

--
Doug Harrison



Mon, 31 Jul 2000 03:00:00 GMT  
 Pointers to member functions?

Quote:


>> An a "C" program, I have these declarations:

>> [pointer to a member syntax discussion deleted.]

>The other answers in this thread have answered the author's concerns. It
>has been my experience that there are usually better ways than pointer to
>member functions to select a function at run-time. Lets suppose we have
>a set of 3 functions which need to be invoked depending on the situation.
>In C pointer to member syntax is used
>to cause a method to get selected at runtime, or for use in a callback
>function.

>Sure it gets the job done, but then the usage is often pretty unwieldly by
>the user of the library.

The other strategy to try is the function object, or functoid.  The STL
makes
extensive use of classes of these types.

A function object is any object that has operator () overridden.

You can pass these objects to functions that expect callbacks.

(An added advantage is that these functions can be inlined.)

-bill



Tue, 01 Aug 2000 03:00:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Pointers to member functions as function arguments

2. Function Pointer for Member Function

3. Function pointer for Member Function

4. Function Pointers to Member Functions

5. Pointer-to-member function question

6. Pointer to member function as parameter?

7. Pointers to member functions

8. null pointer to member function.

9. Pointer to Member Function

10. pointer-to-member-function as template argument ??

11. Pointer of Member Functions from a struct

12. pointer to member function/variable info?

 

 
Powered by phpBB® Forum Software