Thanks! Now it's clearer to me. So I should move the multimap outside of the class and after an object of that class is created, right?
Printable View
Thanks! Now it's clearer to me. So I should move the multimap outside of the class and after an object of that class is created, right?
The bottom line is that you need an object created to call non-static member functions, whether or not you're calling the function using a pointer. That's just basic C++.
So a pointer to the non-static member function has to follow the same rules, thus the syntax I showed you earlier.Code:class X
{
public:
void DoSomething();
};
int main()
{
// how do you call DoSomething()?
// not like this:
// X::DoSomething();
//...
// like this -- create an object...
X someObject;
someObject.DoSomething();
}
Regards,
Paul McKenzie
Understood. Thank you very much!
OK I hope I am getting close to the right track: failed to find the syntax to call std::mem_fun and confused by std::function and std::bind, I found this:
http://www.goingware.com/tips/member-pointers.html
This is exactly what I needed! The example code follows:Quote:
... One of the best uses for member function pointers is caching the outcome of a decision over which of several member functions should be called in a particular circumstance. If a decision is always going to yield the same result, then it may be faster and even cleaner to make the decision just once ahead of time, then store the outcome in the form of a member function pointer. This is especially advantageous when the decision will be made repeatedly in a loop. ...
Then I found this:Code:#include <exception>
class Test {
public:
Test( long inFactor );
long TimesOne( long inToMultiply ) const;
long TimesTwo( long inToMultiply ) const;
long TimesThree( long inToMultiply ) const;
long MultiplyIt( long inToMultiply ) const;
private:
typedef long (Test::*Multiplier)( long inToMultiply ) const;
long mFactor;
Multiplier mMultFuncPtr;
static Multiplier GetFunctionPointer( long inFactor ); };
Test::Test( long inFactor )
: mFactor( inFactor ),
mMultFuncPtr( GetFunctionPointer( mFactor ) ) {
return; }
Test::Multiplier Test::GetFunctionPointer( long inFactor ) {
switch ( inFactor ){
// Decision only made once!
case 1:
return &Test::TimesOne;
break;
case 2:
return &Test::TimesTwo;
break;
case 3:
return &Test::TimesThree;
break;
default:
throw std::exception(); } }
long Test::MultiplyIt( long inToMultiply ) const {
// Using cached decision result
return (this->*mMultFuncPtr)( inToMultiply ); }
void MultiplyThem( long inFactor ) {
Test myTest( 2 );
long product;
for ( long i = 0; i < 1000000; ++i )
product = myTest.MultiplyIt( i ); }
http://www.codeguru.com/cpp/cpp/arti...r-Function.htm
Again exactly what I am trying to do! The example code follows:Quote:
... An important application of pointer-to-member functions is to generate the response events according to inputs. ...
Following the two examples I put together something like this:Code:
- #include <stdio.h>
- #include <string>
- #include <iostream>
- class Printer{//An abstract printing machine
- public:
- void Copy(char * buff, const char * source){//copy the file
- strcpy(buff, source);
- }
- void Append(char * buff, const char * source){//extend the file
- strcat(buff, source);
- }
- };
- enum OPTIONS { COPY, APPEND };//two possible commands in the menu.
- typedef void(Printer::*PTR) (char*, const char*);//pointer-to-member function
- void working(OPTIONS option,
- Printer* machine,
- char* buff,
- const char* infostr){
- PTR pmf[2]= {&Printer::Copy, &Printer::Append}; //pointer array
- switch (option){
- case COPY:
- (machine->*pmf[COPY])(buff, infostr);
- break;
- case APPEND:
- (machine->*pmf[APPEND])(buff, infostr);
- break;
- }
- }
- int main(){
- OPTIONS option;
- Printer machine;
- char buff[40];//target
- working(COPY, &machine, buff, "Strings ");
- working(APPEND, &machine, buff, "are concatenated! ");
- std::cout<<buff<<std::endl;
- }
- Output:
- Strings are concatenated!
It compiles and seems to run OK but I am not sure if it is legal or correct. Please comment. Thanks!Code:class MyClass {
...
int map_formula(int id, ...);
...
void fna();
void fnb();
...
void run(int id, ...);
...
}
typedef void(MyClass::*memfnptr_t) ();//pointer-to-member function
multimap<int, memfnptr_t> mm_id_fn;
int MyClass::map_formula(int id, ...){
// will be called multiple times with different values of id to construct the multimap
...
mm_id_fn.insert(pair<int,memfnptr_t>(id,&MyClass::fna));
...
mm_id_fn.insert(pair<int,memfnptr_t>(id,&MyClass::fnb));
...
}
void MyClass::run(int id, ...){
multimap<int,memfnptr_t>::iterator it;
pair<multimap<int,memfnptr_t>::iterator, multimap<int,memfnptr_t>::iterator> ret;
it = mm_id_fn.find(id);
if (it!=mm_id_fn.end()){
ret = mm_id_fn.equal_range(id); // find all functions pointed by id
for (it = ret.first; it != ret.second; ++it){
memfnptr_t fn=(*it).second;
(this->*fn)();
}
cout << endl;
}
}
I have to move the multimap back into the class otherwise different instances of the class share the same multimap and interfere with one another. Now the code looks something like
It seems to work so far. Please comment if there is anything wrong with this approach. Also I wonder if the typedef can be hidden inside the class as well? Thanks!Code:class MyClass;
typedef void(MyClass::*memfnptr_t) ();//pointer-to-member function
class MyClass {
...
multimap<int, memfnptr_t> mm_id_fn;
...
int map_formula(int id, ...);
...
void fna();
void fnb();
...
void run(int id, ...);
...
}
... // the rest is the same as before