本文介绍了参数数未知的C ++函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要有关C ++的帮助!

I need some help with C++, please!

我正在为一个小型的基于文本的游戏编写命令解析器,但遇到了一些问题.解析器应该读取并解析播放器输入的命令.

I'm writing a command parser for a small text-based game, and I've run into some problems. The parser is supposed to read and parse commands entered by the player.

最明显,最直接的解决方案可能是这样的(用伪代码编写):

The most obvious and straightforward solution to this could be something like this (written in pseudo-code):

command <- read input from the player
if command == COMMAND1
    do command1
else if command == COMMAND 2
    do command2
...

我正在用C ++编写,因此我想我可以通过使用关联映射和函数指针来解决此问题.我对使用函数指针不那么熟悉,所以这可能就是我遇到问题的原因.我想要做的是让循环等待输入,解析插入的输入并根据给定的命令调用函数.这是一些C ++式的伪代码,描述了我的想法:

I'm writing in C++, so I was thinking I could solve this by using an associative map and function pointers. I'm not that familiar with using functions pointers, so that may be why I'm having problems. What I want to do, is to have some sort of loop that waits for input, parse the input that is inserted, and calls a function depending on the command given. Here's some C++-ish pseudo-code describing what I am thinking:

while(1) {
 cin >> input;
 char * tok = strtok(input, " ")
 functionpointer fptr = command_map.find(tok);
 ... // here, I get stuck on what to do..
}

所以我希望我对自己想要发生的事情有所了解.玩家可能输入了类似的内容

So I hope I make myself somewhat clear on what I want to happen. The player could have had input something like

> go south

我可以用类似以下的代码来完成代码:

and I could have finished the code with something like:

destination = strtok(NULL, " ");
fptr(destination);

基本上,从映射返回的值将是执行命令"go"的函数,并且该函数显然带有一个参数,即目的地.同样,这是一些C ++伪代码.这样我就覆盖了命令"go".但现在说我想拥有以下命令:

Basically, the value returned from the map would be the function that performs the command "go", and that function apparently takes one argument, the destination. Again, this is some C++-pseudo-ish code. So I got the command "go" covered. But now say that I want to have the follwing command:

> attack troll with sword

现在,我觉得我需要做类似的事情:

Now I feel that I need to do something like:

while(1) {
 cin >> input;
 char * tok = strtok(input, " ")
 functionpointer fptr = command_map.find(tok);
 if(tok == "go"){
    destination = strtok(NULL, " ");
    fptr(destination);
 } else if (tok == "attack") {
    target = strtok(NULL, " ");
    weapon = strtok(NULL, " ");
    fptr(target, weapon);
   }
}

同样,这是伪代码.您可能会看到我迷上的东西:我有这个函数指针映射,但是因为我有可变数量的参数和参数类型,因为我想根据输入的内容来调用不同的函数,所以我可以我刚完成此操作时没有像我首先向您展示的那样具有映射和函数指针.有什么办法可以使它更通用,而不必使用一些if-else子句来确定要传递多少个参数?

Again, this is pseudo-code. You probably see what I get hung up on: I have this map of functions pointers, but because I have variable number of arguments and type of arguments because I want to call different functions depending on what I got as the input, so I could've just done this without a map and function pointers like I showed you first. Is there some way I can make this more general, without having to have some if-else clause to figure out how many arguments to pass?

希望您能理解我需要的帮助:)感谢您的阅读!

I hope you understand what I need help with :) Thank you for reading!

推荐答案

更好的解决方案是让所有函数都采用相同的参数.一个好主意是首先完全标记您的输入(例如,转换为字符串向量),然后将该数组传递给函数.然后,您可以使用关联容器(例如哈希表或std::map)将命令令牌映射到处理函数.

A better solution would be to have all of your functions take the same arguments. A good idea would be to first completely tokenize your input (say, into a vector of strings), and then pass that array to the functions. You could then use an associative container (such as a hash table or a std::map) to map command tokens to handler functions.

例如:

typedef std::vector<std::string> TokenArray;
typedef void (*CommandHandler)(const TokenArray&);
typedef std::map<std::string, CommandHandler> CommandMap;
void OnGo(const TokenArray& tokens)
{
    // handle "go" command
}
void OnAttack(const TokenArray& tokens)
{
    // handle "attack" command
}
// etc.

CommandMap handlers;
handlers["go"] = &OnGo;
handlers["attack"] = &OnAttack;
// etc.

while(1) {
  std::string input;
  cin >> input;
  std::istringstream tokenizer(input);
  TokenArray tokens;
  std::string token;
  while(tokenizer >> token)  // Tokenize input into whitespace-separated tokens
    tokens.push_back(token);
  CommandMap::iterator handler = handlers.find(tokens[0]);
  if(handler != handlers.end())
      (*handler)(tokens);  // call the handler
  else
      ; // handle unknown command
}

这篇关于参数数未知的C ++函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 19:25