Reputation: 7993
I have this function in some library:
class myConsole
{
void addCommand( std::string command, void* fn );
...
}
and in my class I have this function:
void myApp::TestFn( const std::vector<std::string> & args )
{
// do something
}
in the same class I call this:
void myApp::initApp( )
{
myConsole::getSingleton( ).addCommand( "FirstTest", &myApp::TestFn );
}
but this gives me this error:
error c2664 cannot convert parameter 2 from 'void(__thiscall myApp::*)(const std::vector<_Ty>&)' to 'void *'
how can I solve this?
thanks in advance!
Upvotes: 2
Views: 1568
Reputation: 27123
You should avoid void*
, especially when trying to use function pointers. I'm going to assume that you are looking only at member-function pointers in the myApp
class, and that you are only interested in member-function pointers which take const std::vector<std::string> &args
as an argument. This typedef will create the appropriate type and call it MemFunType
typedef void (myApp :: * MemFunType) (const std::vector<std::string> &);
Here is a complete example (on ideone), where there are two different member-functions you may be interested in, TestFn
and TestFnBackwards
. This example probably isn't very useful, but it gives some examples of member-function pointers.
#include<iostream>
#include<vector>
using namespace std;
struct myApp;
struct myConsole
{
typedef void (myApp :: * MemFunType) (const std::vector<std::string> &);
void addCommand( std::string command, MemFunType fn );
};
struct myApp {
void TestFn( const std::vector<std::string> & args ) {
cout << " TestFn" << endl;
for(std :: vector<std::string> :: const_iterator i = args.begin(); i!=args.end(); i++) {
cout << *i << endl;
}
}
void TestFnBackwards( const std::vector<std::string> & args ) {
cout << " TestFnBackwards" << endl;
for(std :: vector<std::string> :: const_reverse_iterator i = args.rbegin(); i!=args.rend(); i++) {
cout << *i << endl;
}
}
static myApp & getSingleton();
} ma;
myApp& myApp :: getSingleton() {
return ma;
}
void myConsole :: addCommand( std::string , MemFunType fn ) {
vector<string> words;
words.push_back("hello");
words.push_back("world");
myApp &ma = myApp :: getSingleton();
(ma.*fn)(words); // execute the member on the singleton object, using the words as the argument.
}
int main() {
myConsole m;
m.addCommand( "FirstTest", &myApp::TestFn );
m.addCommand( "FirstTest", &myApp::TestFnBackwards );
}
Upvotes: 1
Reputation: 14078
The problem here is that you are trying to pass a class method as it were a void *
pointer. This cannot be done.
The right way of doing this is by using templates for the void addCommand (std::string, void *)
method. Something like
class myConsole {
template <typename T>
void addCommand( std::string command, T f);
};
struct Callback {
myApp &app;
Callback (myApp &a) : app(a) {
}
void operator() (const std::vector<std::string> &args) {
app.TestFn(args);
}
};
void myApp::initApp( )
{
myConsole::getSingleton( ).addCommand( "FirstTest", Callback(*this) );
}
This gives you the callback principle in C++, but I think you need something more flexible than this solution, since you actually want to choose automatically the command that will be executed by the callback (in this case TestFn
).
Upvotes: 1