Re: One question about table driven and function pointer
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! ]