Passing member function pointer

Started by
7 comments, last by JohnnyCode 14 years, 3 months ago
A while ago, I tried to implement a Quake-ish style console, but it was written in C. I'm not too comfortable with C++ yet so some (read: many) concepts elude me. I'm revisiting this now in an attempt to get some STL into my system. I basically built an array of function pointers and compared the string the user entered, so on and so forth. The problem comes up with member functions, since I have to wrap them in another static function in order to pass them to my function. Wrapping every single function that is going to be used in the console is a pretty ugly solution. Is there a more elegant way?
Advertisement
In C++ you may want to avoid the static function pointers and use object pointers (references) instead.
In general, you do not want to use a pointer to a member function in C++ (altough there are always exceptions) as this is more C like approch.
Boost.Function
I have absolutely zero experience with boost. My compiler has some C++0x stuff implemented, so std::function / bind are available.


I kind of got it working, it calls the function, but also it the argument specified within bind. What I want to do is give it my own argument


void con::echo(const std::string& str){	std::cout << str;}


so when the function pointer gets called later down the line, the arg I give it is seemingly meaningless as it just goes with whatever was bind'd.

say someone types 'print BUTTS' into the console.
it would parse 'print' as the command name and 'BUTTS' as the argument.

This is the behavior I'm looking for. This was easy to implement with function pointers, but it seems somewhat convoluted when classes and members are introduced. :|
Quote:I kind of got it working, it calls the function, but also it the argument specified within bind. What I want to do is give it my own argument


void con::echo(const std::string& str){	std::cout << str;}


so when the function pointer gets called later down the line, the arg I give it is seemingly meaningless as it just goes with whatever was bind'd.
You may be looking for the _1, _2, _*, symbols that are part of the bind library/module. They're used as 'placeholders' indicating that the specified argument will be provided when the function object is invoked. When the bound function is a member function, these symbols can serve as placeholders for the object on which the member function is to be invoked, and/or one or more of the arguments to that function.

If that doesn't clear things up, post back and someone can probably post a simple code sample demonstrating how to use these placeholders.
I implemented something like this using an std::map of boost::function (I think now std::function in MSVC++ 2010). I mapped the function name (ie, print) to the function which took a string, the parameter of the function, as the parameter of the function.

Some code snippets that might help you.
std::map<std::string, boost::function<void, const std::string&> > commands;void console_print(const std::string& args) {    std::cout << args << std::endl;}commands["print"] = &console_print;// Executing a command given a command name and the arguments.if (commands.count(command_name) > 0)     commands[command_name](args); // Executes the command.else    std::cout << "unknown command '" << command_name << "'" << std::endl;
Thanks both of you, that seems to have put me on the right track.
you do not wrap them in a static function. Declare a global function (not a member of any class) of the same type as the member function you want to call. Like this:

void Gfunc(parameters, void * caller)
{
caller->wantedmember(parameters,caller);
}

When you declare a function pointer, always add to the parameters ",void* caller".
Where you invoke the function pointer you write:

m_funcpoi(params,this);

It will invoke the function on this-instance;
If you want to invoke the function on a different instance, even with different class, you should have a member variable that points to instance.

if (m_pOperatingOnPointer)
m_funcpoi(params,m_pOperatingOnPOinter);

this is how you define a member function you want to assign.

void CClass::membertoassign(parameters,void* caller)
{
(CMyType*) workwith=(CMyType*)caller;
workwith->...
...
}
You assign this global function to all instances, so you can assign it in constructor of class you use member of.

This topic is closed to new replies.

Advertisement