How to declare C ++ mem_fn (member_function) in function declaration?

I understand the main problem when passing the address of a member function outside of my class. I get the feeling that mem_fn () might be the solution, but I'm having problems with specifics.

I have a member function in class p that is currently declared as

typedef void (*valNamedFlagsCallback)(const int, const bool); bool valNamedFlags(const OptBlk *operand, const char *description_of_value_or_NULL, const int subscripts[], const char *names[], valNamedFlagsCallback callBack); 

In class e, I'm trying to call valNamedFlags with

 pInstance->valNamedFlags(operand, "Statement types", statementsSubscripts, statementsNames, std::mem_fn(&e::setStatement)); 

(I started without mem_fn (), but of course I have classic problems with pointers to member functions. I tried using both parameters: amer; e :: setStatement and just plain & setStatement.)

FWIW, setStatement is prototyped as

  void setStatement(const int ifcid, const bool isAffirmative); 

Everything works if I exclude mem_fn () and declare setStatement static. I simply point out that this is a way of saying that I eliminated all other possible problems; my only problem is the "member function pointers" problem. Unfortunately, setStatement () must be a member function, not static.

The specific error that I get in MS VS 2010 is

bool p :: valNamedFlags (const OptBlk *, const char *, const int [], const char * [], p :: valNamedFlagsCallback) ': cannot convert parameter 5 from' std :: tr1 :: _Mem_fn3 <_Rx, _Pmf , _Arg0, _Arg1, _Arg2> 'to' p :: valNamedFlagsCallback '

I would like to keep the callback declaration independent of class e; that is, I do not want to go to

 typedef void (*e::valNamedFlagsCallback)(const int, const bool); 

because I want to keep p more generalized than that.

Is mem_fn () the right solution or am I not in the database? If so, how should I declare a callback in the valNamedFlags () prototype?

Or should I take a different approach?

+6
source share
3 answers

In fact, you will have a problem with similar binder materials, like some of them, since your callback is defined as a simple pointer to a function, not a callable.

If you can afford to do this, you can change your

 typedef void (*valNamedFlagsCallback)(const int, const bool); 

to something like

 typedef std::function<void(int, bool)> valNamedFlagsCallback 

(also noting that const with respect to the parameters of the value does not affect the function signature), you can use std::bind() ,

 using namespace std::placeholders; pInstance->valNamedFlags(operand, "Statement types", statementsSubscripts, statementsNames, std::bind(&E::setStatement, e, _1, _2)); 

or you can use lambdas:

 pInstance->valNamedFlags(operand, "Statement types", statementsSubscripts, statementsNames, [&](int i, bool b) { e->setStatement(i, b); }); 

If you have to save it as a simple function, you will have to send one that refers to the correct object as a global / static variable.

+6
source

You need a bind instance to call through a member function pointer. (i.e. std::bind(&e::setStatement, eInstance, _1, _2) , suppose eInstance is a pointer to an object of class e ).

 using namespace std::placeholders; // for _1, _2, _3... pInstance->valNamedFlags(operand, "Statement types", statementsSubscripts, statementsNames, std::bind(&e::setStatement, eInstance, _1, _2)); 

Note that the return value of std::bind (which is not specified) does not match the pointer type of the free function valNamedFlagsCallback , one solution is to use std::function .

 typedef std::function<void(const int, const bool)> valNamedFlagsCallback; 

Simplified Demo

+5
source

Got! THANK YOU ALL!!!

Prototype:

 bool valNamedFlags(const OptBlk *operand, const char *description_of_value_or_NULL, const int subscripts[], const char *names[], std::function<void(int,bool)> callBack); 

Call:

 valNamedFlags(..., std::bind(&e::setStatement, this, _1, _2)); 

It actually executes and calls setStatement with the corresponding arguments.

0
source

All Articles