Function Pointers

Started by
3 comments, last by Zahlman 16 years, 11 months ago
I'm trying to call a function within an object, and it won't compile (MSVS 2003).

#include <iostream>

using std::cout;

int Foo2()
{
	cout << "Foo2\n";
	return 0;
}

class Ctest
{
public:
	int x;
	Ctest() { x = 9; }
	void TestFunct(int (*functptr)()) {
		cout << "x:  " << x << "\n";
		int p = (*functptr)();
	}
	int Foo2() { cout << "Ctest::Foo2\n"; return 0; }
};

void main()
{
	Ctest t;
	t.TestFunct(Ctest::Foo2);
	// this results in
	// error C2664: 'Ctest::TestFunct' : cannot convert parameter 1 from      
        //'int (__thiscall Ctest::* )(void)' to 'int (__cdecl *)(void)'

}

Sooooo .... what am I doing wrong?
~Argonaut________________________________Why "~Argonaut"? It's all just a mathematical expression denoting a close approximation of "Argonaut", which is irrational and can't be precisely defined.
Advertisement
The problem is that you're trying to use a non-static member method. Because of this, there is an implicit "this" argument to the method (which is why all member methods have the magical "this" pointer). Because of this, I think that member methods use a different calling convention (__thiscall, from the error message), that is incompatible with a non-member method's calling convention.

One way to fix your compile error is to make Ctest::Foo2 static:

static int Foo2() { cout << "Ctest::Foo2\n"; return 0; }
If you are still interested in calling a nonstatic member function from a function pointer, you would have to rewrite the functions.

The main problem is that member functions must be declared as such in the function pointer.
Therefore, Ctest::*functptr needs to be used over just *functptr:
[SOURCE]void TestFunct(int (Ctest::*functptr)()){     /*Stuff*/}[/SOURCE]


The calling convention is different as well, as the "this" argument needs to be clarified as well.
Instead of just *functptr(), one would need to call this->*fuctptr(), to get a "this" pointer so the function knows what it needs to be called on.

Overall:
[SOURCE]#include <iostream>using std::cout;int Foo2(){	cout << "Foo2\n";	return 0;}class Ctest{public:	int x;	Ctest() { x = 9; }	void TestFunct(int (Ctest::*functptr)()) { //Modified function pointer declaration		cout << "x:  " << x << "\n";		int p = (this->*functptr)(); //Modified function call	}	int Foo2() { cout << "Ctest::Foo2\n"; return 0; }};int main(){	Ctest t;	t.TestFunct(&Ctest::Foo2);        //This works.}

[size=1]Visit my website, rawrrawr.com

Cool! Thanks for the insight!

This was just a theoretical experiment. The real question is how is this applicable? I'm thinking this might be useful for dynamically calling functions within an object, but I'm having a hard time wrapping my mind around how this is useful over other methodologies (direct method calls). Any insight?
~Argonaut________________________________Why "~Argonaut"? It's all just a mathematical expression denoting a close approximation of "Argonaut", which is irrational and can't be precisely defined.
Quote:Original post by argonaut
Cool! Thanks for the insight!

This was just a theoretical experiment. The real question is how is this applicable? I'm thinking this might be useful for dynamically calling functions within an object, but I'm having a hard time wrapping my mind around how this is useful over other methodologies (direct method calls). Any insight?


Don't worry about it. When you find a use for it, you'll know. Typically it gets used for a really ugly implementation of the Command pattern. Typically at this point, people will tell you that instead of trying to deal with pointers to member functions, you should try out functors, instead.

If you come at it from a purely OO angle instead, you'll likely get a pretty, but non-C++-idiomatic, implementation of the Command pattern. At which point, people will just tell you politely that in C++, we spell that 'Execute()' function in the Command base class' interface as 'operator()()'. :)

This topic is closed to new replies.

Advertisement