pointer to any member function of any class

J

joosteto

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

Victor Bazarov

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

Victor Bazarov

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
 
J

joosteto

Victor said:
(e-mail address removed) 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?
 
V

Victor Bazarov

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

joosteto

Victor said:
[..]
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
 
J

Jim Langston

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

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
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top