From: Daniel Krügler on 3 Nov 2009 18:19 On 4 Nov., 00:28, Ben <wudehui2...(a)gmail.com> wrote: > Hi I need to associate a string with a function. I define the > following table > > struct COMMAND { > const WCHAR * name; > void T::*proc(int); > }; Please stay away from unnecessary names that complicate a simple problem. For the following I assume that instead of WCHAR you would have written char. Note also that void T::*proc(int); is no valid pointer to member function declaration. I assume for the following that you meant void (T::*proc)(int); given some class type T. > static const COMMAND commands[] = { > {"north", fun0}, > {"east", fun1}, > {"south", fun2}, > {"west", fun3}, > }; > > However I would like to have fun2 and fun3 corresponds to another type > of function > T::*proc(string) > > How can I do it? To give a reasonable answer to that question it would be helpful to understand how the *user* of commands should know when (s)he has to call the array elements with an int argument and when with a (std::)string(?) argument? I would try to find an answer to this question first, because it might point to a solution where a) the caller of commands actually would prefer to provide no explicit arguments at all. boost::bind would allow the creation of such function wrappers including direct argument binding. b) it shows that a single COMMAND[] is not what is needed, but actually two (or more) arrays, e.g. by redefining COMMAND as a template: template<typename ArgType> struct COMMAND { const char* name; void (T::*proc)(ArgType); }; ending up in static const COMMAND<int> int_commands[] = { {"north", &T::fun0}, {"east", &T::fun1}, {"south", &T::fun2}, {"west", &T::fun3}, }; static const COMMAND<const std::string&> str_commands[] = { {"right", &T::fun4}, {"left", &T::fun5}, {"up", &T::fun6}, {"down", &T::fun7}, }; HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Nick Hounsome on 3 Nov 2009 18:18 On 3 Nov, 23:28, Ben <wudehui2...(a)gmail.com> wrote: > Hi I need to associate a string with a function. I define the > following table > > struct COMMAND { > const WCHAR * name; > void T::*proc(int); > }; > > static const COMMAND commands[] = { > {"north", fun0}, > {"east", fun1}, > {"south", fun2}, > {"west", fun3}, > > }; > > However I would like to have fun2 and fun3 corresponds to another type > of function > T::*proc(string) > > How can I do it? How would you know what parameter (int or string) to supply to the call? If you answer this then we can suggest an appropriate answer. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Olivier on 5 Nov 2009 01:42 you could eventually do it the following way : #include <map> #include <iostream> template< typename Arg > class command_list { public: void register_command( char const *name, void (*cb) ( Arg ) ) { command_map[name] = cb; } void call( char const *name, Arg arg ) { command_map[name](arg); } private: std::map<std::string, void (*)( Arg )> command_map; }; class commands : public command_list<std::string> , public command_list<int> { public: template< typename Arg > void register_command( char const *name, void (*cb) ( Arg ) ) { static_cast<command_list<Arg> &>(*this).register_command (name, cb); } template< typename Arg > void operator()( char const *name, Arg arg ) { static_cast<command_list<Arg> &>(*this).call(name, arg); } }; void north( int i ) { std::cerr << "in north( int i = " << i << " ) \n"; } void south( std::string s ) { std::cerr << "in south( std::string const &s = '" << s << "' )\n"; } void east( std::string s ) { std::cerr << "in east( std::string const &s = '" << s << "' )\n"; } void west( int i ) { std::cerr << "in west( int i = " << i << " ) \n"; } int main( ) { commands cmds; cmds.register_command("north", &north); cmds.register_command("south", &south); cmds.register_command("east", &east); cmds.register_command("west", &west); cmds("north", 0); cmds("south", std::string("hello")); cmds("east", std::string("again")); cmds("west", 1); } This is a very simple implementation, and there are several points you'll want to address : - You most probably want to check for invalid names and duplicate registered functions. - Argument passing is not perfect as everything is passed by copy. That can be fixed with a little template magic. - You can't rely on implicit conversions to call commands. - Changes can be made to the internals of 'command_list' to use a static map. -- Olivier [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Pages: 1 2 Prev: An stl list of function pointers Next: When are data structures copied |