I already know the basics about functors, how they are created and so on. I now have a specific code that would probably benefit from being converted to functors:
It's about a console input. If the user enters text and presses enter than it tries to execute the entered text as a command. Currently the available commands are stored in a std::map<std::string, (void*)(std::string)>
where map.first is the name of the command and map.second is the pointer to a function containing the code for this command.
If I now convert this to functors, what would be the best way to do so? Would I simply replace the function pointer by the actual functor objects? Or would remove the map and simply call the functor with the command string (commandFunctor("command")
)?
If the second: What would the best way such 开发者_运维百科a functor should look like? Should I then only create ONE functor class and in it's operator() place a if-else-if-else... checking for the commands and store the code into it?
Or should I create a new functor class for each command and call the functor that corresponds to this command?
So, in short: User enters command. Command is looked up. If comnmand exists then execute its code. How to do this in the most efficietly way with functors?
I would suggest using a std::map<std::string, boost::function<void(std::string)> >
. Or, if you have access to a C++0x standard library, you can use std::function
instead of boost::function
.
A boost/std::function
is a callable object that can store anything that is callable with the function type you specify. So the user can give you a function pointer, a functor of a type that they create, or even a boost/std::bind
object that does function composition.
I would stick with the general form of what you have, but use a std::map<std::string, std::tr1::function>
to store the commands (i'm using std::tr1::function, but you can use whatever functor class fits)
Currently, you use the map to determine which function pointer to be called, based on the discriminator (or string id, or whatever you want to call it). Replacing it with a functor that just gets passed a string (say, commandFunctor("command")), you'll just have to move the mapping logic to that function.
You'll still need the map, but as you noticed, you can definitely replace the function pointer with a functor, and depending on your compiler/version/etc, you can use the std::tr1::function or boost, or whatever else you might have.
精彩评论