Passing methods as arguments to other methods in C++

Hello and thank you for reading my post.

I have several methods which begin and end the same: file opening at the beginning, information collecting from the files prior to a specific treatment, file closing at the end... Pretty much like this:

1
2
3
4
5
6
7
8
9
10
11
A method
// Pre-operations
// Another method call
// Post-operations

A method 2
// Pre-operations
// Another method call 2
// Post-operations

...


Here is my question:
do I have to duplicate the code for each "Another method call i"
or can I pass the methods "Another method call i" to a common method M?

I'm not sure whether I can pass methods as arguments to other methods in C++ or not... Can I? How?

If it is possible, can you tell me how you would proceed with the following simplified example? I've put question marks ??? where I don't know what to code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int AClass::anotherMethod1(int i)
{
	return (i + 1);
}

long AClass::anotherMethod2(long l1, long l2)
{
	return (l1 + l2);
}

void AClass::aCommonMethod(???)
{
	cout << "Start" << endl;

	// Call to either:
	// anotherMethod1()
	// or to anotherMethod2().

	cout << "End" << endl;
}

int main()
{
AClass aclass;
int i = 0;
long l1 = 1;
long l2 = 2;

	// Call with anotherMethod1()
	aclass.aCommonMethod(???);
	// Call with anotherMethod2()
	aclass.aCommonMethod(???);

	return 0;
}


Can you help me?
Thank you and best regards.
Yes, you can. But the syntax is uglier than function pointers.
As a work around, you could pass functors
1
2
3
4
class Functor{
public:
   return_type operator() (/*args*/);
};
then make the common one
1
2
3
4
5
6
template<class Functor>
void foo(Functor f){
   //pre
   f(/*args*/);
   //post
}


However, your example is really bad. Those shouldn't be methods as they don't use the state of the object.
Hello and thank you for your answer.

I don't think that my example is bad.
I just wanted to highlight the fact that the methods at stake may not have the same prototypes.
I made these methods simple so that no one would have to concentrate on what the methods actually do because this is not what I'm interested in.

More important: I do not see how to apply the "Functor" class you mentioned to this example.
Second: I have nothing against function pointers especially if they allow me to do what I want to do.
I just need a little help to understand how to use either one method or the other in that example.

Thank you and best regards.
> I just wanted to highlight the fact that the methods at stake may not have the same prototypes.
I didn't see that, sorry. However, if they have a different number of parameters ¿how do you expect to call them?

Variadic templates (c++0b) may solve that, didn't play with them so don't know.

Or just go with an standard prototype, letting the function to transform it
By instance void foo(void *data);
or using functors (not tested)
1
2
template<class Functor>
typename Functor::return_type foo( Functor f, typename Functor::arg_type arg );
> More important: I do not see how to apply the "Functor" class you mentioned to this example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
template <class Functor>
void container::traverse( Functor f ){
   for(iterator it=begin(); it!=end(); ++it)
      f(*it);
}

class Clamp{
private:
   int lower, upper;
public:
   Clamp(int lower, int upper);
   void operator()(int &value){
      if(value<lower) value=lower;
      if(value>upper) value=upper;
   }
};

class Print{
private:
   char separator;
public:
   Print(char separator);
   void operator()(int value){
      std::cout << value << separator;
   }
};


Container c;
c.traverse( Clamp(0, 100) );
c.traverse( Print(' ') );
Checkout std::{for_each,transform} and lambdas
For method pointers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

class bar{
public:
   void print(int value){
      std::cout << value << ' ';
   }
};

class foo{
public:
   typedef void ((bar::*method)(int)); //for sanity

   void common(method m){
      bar obj; //as it is a method, we need an object
      (obj.*m)(42); //dereferencing the method pointer
   }

};

int main(int argc, char **argv){
   foo::method p = &bar::print; //choosing the method
   foo test;
   test.common(p);
   return 0;
}



Sorry for the multiple post, I'm having some issues with the page/browser/javascript (don't know whom to blame)
Last edited on
Sorry for not having been clear enough and thank you for all this material.
I'm going to study this carefully...
Best regards.
1
2
3
4
5
ReturnType (SomeClass::*NameOfMemberFunctionPointer)(ParamTypes);
//...
NameOfmemberFunctionPointer = &SomeClass::SomeMemberFunction;
//...
SomeIntance.*NameOfMemberFunctionPointer(params);
It's pretty ugly, which is why ne555 used a typedef and also why he originally tried convincing you to use functors.

Also, unlike function pointers, which have a non-pointer form and also a reference form, member function pointers have only their pointer form.
Last edited on
Topic archived. No new replies allowed.