Passing member functions as parameters / C ++

I would like to implement class b in C ++, where it would be possible to perform some iteration through a set of elements encapsulating the type of this iterator. For instance:

b_object.for_each_x_do(function_f); 

so function_f will get all x members and do everything. Let them talk:

 void function_f(x_member_type x){ cout << x << endl; } 

Ok Therefore, I am trying to achieve this with code, for example:

 class b{ int *x; public: void foreach_x_do(void (*f)(int)){ while(*x++) // or any kind of iteration through x f(*x); } }; class a{ b b_inst; public: void f(int x) { } a(){ b_inst.foreach_x_do(f); // by mistake it was b_inst.foreach_x_do(f)(), however this wasn't the point at all. } ~a(){} }; int main(){} 

However, I get this error, compilation time:

fp.cpp: In the constructor 'a::a()' :
fp.cpp: 17: error: there is no corresponding function to call 'b::foreach_x_do(<unresolved overloaded function type>)'
fp.cpp: 6: note: candidates: void b::foreach_x_do(void (*)(int))

Can anyone help get it to compile?

+4
source share
6 answers

It should be simple:

 b_inst.foreach_x_do(f); 

You also need to make the static method f , not a non-static member method, since the original signature for your foreach_x_do function is for the autonomous function pointer, not for the pointer function. For example,

 static void f(int x) { } 
+1
source

As @ steveo225 noted, f in this context is of type void (a::*)(int) , not void (*)(int) . There are two approaches to fixing this: the first is to make b::foreach_x_do a member function template that accepts any type being called:

 class b { int* x; public: b() : x() { } template<typename F> void foreach_x_do(F f) { while(*x++) f(*x); } }; class a { b b_inst; public: void f(int x) { } a() : b_inst() { b_inst.foreach_x_do(std::bind(&a::f, this, _1)); } }; 

The second is to save the b::foreach_x_do non-template and use std::function<> instead of the function pointer:

 class b { int* x; public: b() : x() { } void foreach_x_do(std::function<void(int)> const& f) { while(*x++) f(*x); } }; class a { b b_inst; public: void f(int x) { } a() : b_inst() { b_inst.foreach_x_do(std::bind(&a::f, this, _1)); } }; 

In any case, replace std::bind and std::function with your counterparts boost:: if your compiler is too old to supply std:: or std::tr1:: implementations. Also note that if you have a C ++ 11 compiler, you can use lambda instead of bind .

+2
source

The for_each_x_do function expects a pointer to a function, while you are trying to give it a pointer to a member function. These two options do not match. The former can be called directly, while the latter requires a call to an object. I would suggest using std::function or boost::function instead. Sort of:

 void for_each_x_do(function<void (int)> f) { // your code here } 

And then use a binder to create the function object:

 a(){ b_inst.foreach_x_do(bind(&a::f, this, _1)); } 
+1
source

In this line:

  b_inst.foreach_x_do(f)(); 

Delete the second set of parentheses; you do not need them.

  b_inst.foreach_x_do(f); 

should work fine.

0
source

f() is a member function, so relevance is limited to the corresponding object. Some of these solutions will not work yet.

You have two options: to make a static function, in this case it does not matter which object or somehow pass the object.

The second method is clearly explained in this useful FAQ , in particular, on the transfer of member functions.

0
source

Try:

 class b{ int *x; public: void foreach_x_do(void (*f)(int)){ while(*x++) // or any kind of iteration through x (*f)(*x); } 

};

-2
source

All Articles