我昨天才发现函数指针,我正在游戏引擎中实现一个控制台/命令系统。
我认为使用带有字符串键的映射和函数指针值,在选择运行命令时要做的事情时,不需要大量的if语句。
我收到了这个错误:
argument of type
"void (Game::*)(std::string prop, std::string param)"
is incompatible with parameter of type
"void (*)(std::string prop, std::string param)"
现在我想我知道这意味着什么。我可以使用静态函数来解决这个问题,但我希望能够引用Game
的特定实例的方法。
但是函数指针的映射必须能够指向具有return void和2个字符串参数的任何函数。
首先这可能吗?
如果没有,是否可以通过静态成员函数修改实例变量?我对此并不抱太大的希望。
任何帮助都会一如既往地受到赞赏。
答案 0 :(得分:5)
函数指针很糟糕。除非你绝对被迫,否则不要使用它们。相反,更喜欢std::function<void(std::string, std::string)>
和std::bind
/ lambdas。与函数指针不同,它们可以与任何函数对象一起使用,包括绑定成员函数。
std::unordered_map<std::string, std::function<void()>> command_map;
Game game;
Help helper;
command_map["quit"] = [] { exit(); };
command_map["play"] = [&] { game.play(); };
command_map["help"] = [&] { helper.help(); };
答案 1 :(得分:1)
您可以在地图中放置一个对象和一个函数指针。然后调用该函数的静态版本,该函数只调用传入的对象上的函数的真实版本。您可以在Game
中为任意数量的函数重复此操作。
class Game
{
void yourFunc1(std::string prop, std::string param)
{
// do stuff
}
void yourFunc1_static(Game* g, std::string prop, std::string param)
{
g->yourFunc1( prop, param );
}
};
struct MapEntry
{
Game* game;
void (*func)(std::string prop, std::string param);
};
std::map<key_type, MapEntry> _map;
...
_map[key].func( game, "prop", "param" );