pointer to any member function of any class

Discussion in 'C++' started by joosteto@gmail.com, Jul 9, 2006.

  1. Guest

    Subject: pointer to any member function of any class.

    The "C++ FAQ Lite" explains how to hand a pointer to a member function
    to a signal handler etc, but only to a static function (33.2), to
    a fixed class (33.2), any member of a fixed class (33.6), to a fixed
    function of any object (functiods, 33.10).

    What I wanted was to be able to hand any member function of any
    created object to a signal hander etc.

    The code below achieves this, using functiods and templates. The code
    compiles cleanly with "g++ -Wall -pedantic" (g++ 4.0 & 4.1), haven't
    tried other compilers.

    #include <iostream>
    using namespace std;

    //The base-class of the functiod:
    class callbase{
    public:
    virtual ~callbase(){};
    virtual int operator() (int i)=0; //Change/add arguments to taste
    };

    template<class classtocall>
    class calltemplate:public callbase{
    classtocall &object;
    int (classtocall::*methodtocall)(int);
    public:
    calltemplate(classtocall &o,int (classtocall::*m)(int))
    : object(o){
    methodtocall=m;
    }
    int operator()(int i){ //Change/add arguments to taste
    return (object.*methodtocall)(i);
    }
    };

    //the signal handler, system call that starts a thread, etc:
    class handler {
    callbase *m;
    public:
    handler(callbase *b):m(b){};
    int h(int i){
    return (*m)(i); //Change/add arguments to taste
    }
    };

    // A class whose memebers we want to pass to a signal handler etc.
    class worker {
    int i; //data member, just to show each instance is different
    public:
    worker(int j):i(j){}
    int callme(int j){ //Change/add arguments to taste
    return j*i;
    }
    int pleasecall(int j){
    return j+i;
    }
    };

    //need a typedef for each class whose members we want to be called
    typedef calltemplate<worker> call_worker;

    int main (){
    worker w1(3);
    worker w2(7);
    handler h1(new call_worker(w1, &worker::pleasecall));
    handler h2(new call_worker(w2, &worker::callme));

    callbase *members[]={
    new call_worker(w1, &worker::callme),
    new call_worker(w2, &worker::pleasecall)};
    cout<<"h1 met arg 4="<<h1.h(4)<<endl;
    cout<<"h2 met arg 4="<<h2.h(4)<<endl;
    cout<<"arraymember: "<<(*members[0])(3)<<endl;;
    cout<<"arraymember: "<<(*members[1])(3)<<endl;;
    }
    , Jul 9, 2006
    #1
    1. Advertising

  2. wrote:
    > Subject: pointer to any member function of any class.
    >
    > The "C++ FAQ Lite" explains how to hand a pointer to a member function
    > to a signal handler etc, but only to a static function (33.2), to
    > a fixed class (33.2), any member of a fixed class (33.6), to a fixed
    > function of any object (functiods, 33.10).
    >
    > What I wanted was to be able to hand any member function of any
    > created object to a signal hander etc.
    >
    > The code below achieves this, using functiods and templates. The code
    > compiles cleanly with "g++ -Wall -pedantic" (g++ 4.0 & 4.1), haven't
    > tried other compilers.
    >
    > #include <iostream>
    > using namespace std;
    >
    > //The base-class of the functiod:
    > class callbase{
    > public:
    > virtual ~callbase(){};
    > virtual int operator() (int i)=0; //Change/add arguments to taste
    > };
    >
    > template<class classtocall>
    > class calltemplate:public callbase{
    > classtocall &object;
    > int (classtocall::*methodtocall)(int);
    > public:
    > calltemplate(classtocall &o,int (classtocall::*m)(int))
    > : object(o){
    > methodtocall=m;
    > }
    > int operator()(int i){ //Change/add arguments to taste
    > return (object.*methodtocall)(i);
    > }
    > };
    >
    > //the signal handler, system call that starts a thread, etc:
    > class handler {
    > callbase *m;
    > public:
    > handler(callbase *b):m(b){};
    > int h(int i){
    > return (*m)(i); //Change/add arguments to taste
    > }
    > };
    >
    > // A class whose memebers we want to pass to a signal handler etc.
    > class worker {
    > int i; //data member, just to show each instance is different
    > public:
    > worker(int j):i(j){}
    > int callme(int j){ //Change/add arguments to taste
    > return j*i;
    > }
    > int pleasecall(int j){
    > return j+i;
    > }
    > };
    >
    > //need a typedef for each class whose members we want to be called
    > typedef calltemplate<worker> call_worker;
    >
    > int main (){
    > worker w1(3);
    > worker w2(7);
    > handler h1(new call_worker(w1, &worker::pleasecall));
    > handler h2(new call_worker(w2, &worker::callme));
    >
    > callbase *members[]={
    > new call_worker(w1, &worker::callme),
    > new call_worker(w2, &worker::pleasecall)};
    > cout<<"h1 met arg 4="<<h1.h(4)<<endl;
    > cout<<"h2 met arg 4="<<h2.h(4)<<endl;
    > cout<<"arraymember: "<<(*members[0])(3)<<endl;;
    > cout<<"arraymember: "<<(*members[1])(3)<<endl;;
    > }


    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jul 10, 2006
    #2
    1. Advertising

  3. wrote:
    > Subject: pointer to any member function of any class.
    >
    > The "C++ FAQ Lite" explains how to hand a pointer to a member function
    > to a signal handler etc, but only to a static function (33.2), to
    > a fixed class (33.2), any member of a fixed class (33.6), to a fixed
    > function of any object (functiods, 33.10).
    >
    > What I wanted was to be able to hand any member function of any
    > created object to a signal hander etc.
    >
    > The code below achieves this, using functiods and templates. The code
    > compiles cleanly with "g++ -Wall -pedantic" (g++ 4.0 & 4.1), haven't
    > tried other compilers.
    >
    > #include <iostream>
    > using namespace std;
    >
    > //The base-class of the functiod:
    > class callbase{
    > public:
    > virtual ~callbase(){};
    > virtual int operator() (int i)=0; //Change/add arguments to taste
    > };
    >
    > template<class classtocall>
    > class calltemplate:public callbase{
    > classtocall &object;
    > int (classtocall::*methodtocall)(int);
    > public:
    > calltemplate(classtocall &o,int (classtocall::*m)(int))
    > : object(o){
    > methodtocall=m;
    > }
    > int operator()(int i){ //Change/add arguments to taste
    > return (object.*methodtocall)(i);
    > }
    > };
    >
    > //the signal handler, system call that starts a thread, etc:
    > class handler {
    > callbase *m;
    > public:
    > handler(callbase *b):m(b){};
    > int h(int i){
    > return (*m)(i); //Change/add arguments to taste
    > }
    > };
    >
    > // A class whose memebers we want to pass to a signal handler etc.
    > class worker {
    > int i; //data member, just to show each instance is different
    > public:
    > worker(int j):i(j){}
    > int callme(int j){ //Change/add arguments to taste
    > return j*i;
    > }
    > int pleasecall(int j){
    > return j+i;
    > }
    > };
    >
    > //need a typedef for each class whose members we want to be called
    > typedef calltemplate<worker> call_worker;
    >
    > int main (){
    > worker w1(3);
    > worker w2(7);
    > handler h1(new call_worker(w1, &worker::pleasecall));
    > handler h2(new call_worker(w2, &worker::callme));
    >
    > callbase *members[]={
    > new call_worker(w1, &worker::callme),
    > new call_worker(w2, &worker::pleasecall)};
    > cout<<"h1 met arg 4="<<h1.h(4)<<endl;
    > cout<<"h2 met arg 4="<<h2.h(4)<<endl;
    > cout<<"arraymember: "<<(*members[0])(3)<<endl;;
    > cout<<"arraymember: "<<(*members[1])(3)<<endl;;
    > }


    My question would be, how does this accomplish "handing" *any* member
    function of *any* class to a signal handler? I don't see any *signal*
    handler, nor do I see any variation in the member functions. They
    all take a single 'int' argument, they all return 'int', and they are
    all non-cosnt. That's pretty far from "any" in my book.

    Of course, it's possible that my terminology is simply different from
    yours.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jul 10, 2006
    #3
  4. Guest

    Victor Bazarov wrote:
    > wrote:
    > My question would be, how does this accomplish "handing" *any* member
    > function of *any* class to a signal handler? I don't see any *signal*
    > handler, nor do I see any variation in the member functions. They
    > all take a single 'int' argument, they all return 'int', and they are
    > all non-cosnt. That's pretty far from "any" in my book


    True. On the other hand, it's rather difficult to excect to be able to
    call both a func(char*) and a func(int), as in that that would make the
    say signal handler that calls the function rather difficult.

    When the signal handler receives event X, it has information YZ to hand
    to the to-be-called-function -- the types of YZ do not depend on the
    to-be-called-function.

    Anyway, all useful examples I can think of are with a
    function-to-be-called with fixed arguments and return-type.

    Can you think of a situation where functions accepting any argument
    types (and even return types) can be useful?

    --
    Thanks,
    joostje
    , Jul 11, 2006
    #4
  5. wrote:
    > [..]
    > Can you think of a situation where functions accepting any argument
    > types (and even return types) can be useful?


    Very rarely. Interpreters come to mind.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jul 11, 2006
    #5
  6. Guest

    Victor Bazarov wrote:
    > wrote:
    > > [..]
    > > Can you think of a situation where functions accepting any argument
    > > types (and even return types) can be useful?

    >
    > Very rarely. Interpreters come to mind.


    Ah, true. But in that case I suppose the function will be called with
    something like a pointer to the "class arguments" (supplying any number
    of arguments&types), and will return something similar.

    (Rather close to what I do in the real code I use, actually).

    Still, the example I show gives a lot more flexibility than any of the
    examples in the C++ faq lite I found at
    http://www.parashift.com/c -faq-lite/pointers-to-members.html
    , Jul 11, 2006
    #6
  7. Jim Langston Guest

    <> wrote in message
    news:...
    > Victor Bazarov wrote:
    >> wrote:


    > Can you think of a situation where functions accepting any argument
    > types (and even return types) can be useful?


    void ReportValue( const std::string Key, AnyType Value )
    {
    std::stringstream ReportStream;
    ReportStream << CurrentTime << " Key:" << Key << " Value is:" << Value;
    WriteReportString( ReportStream.str() );
    }

    AnyType GetFieldValue( const std::string Key )
    {
    std::string Value = GetValueFromDB( Key );
    TypeEnum ValueType = GetTypeFromDB( Key );
    switch TypeEnum
    {
    case IntType:
    return StrmConvert<int>( Value );
    case BoolType:
    if ( Value == "TRUE" )
    return true;
    else
    return false;
    case...
    }
    Jim Langston, Jul 12, 2006
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Newsgroup - Ann
    Replies:
    5
    Views:
    586
    John Carson
    Jul 30, 2003
  2. Fraser Ross
    Replies:
    4
    Views:
    1,012
    Fraser Ross
    Aug 14, 2004
  3. Replies:
    12
    Views:
    708
    fluden
    Feb 11, 2005
  4. Praetorian
    Replies:
    11
    Views:
    2,329
    James Kanze
    Apr 3, 2008
  5. somenath
    Replies:
    2
    Views:
    140
    somenath
    Aug 29, 2013
Loading...

Share This Page