c ++ std ::异构函数指针的映射

时间:2011-10-20 21:16:38

标签: c++ boost map function-pointers

是否可以存储指向各种异构函数的指针,如:

在标题中:

int  functionA (int param1);
void functionB (void);

基本上这将是我不知道如何写的部分:


typedef ??boost::function<void(void)>?? functionPointer;

之后:

map<char*,functionPointer> _myMap;

在.cpp

void CreateFunctionMap()
{
    _myMap["functionA"] = &functionA;
    _myMap["functionB"] = &functionB;
    ...
}

然后重复使用它:

void execute(int argc, char* argv[])
{

    if(argc>1){
        int param = atoi(argv[1]);
        int answer;
        functionPointer mfp;
        mfp = map[argv[0]];
        answer = *mfp(param);
    }
    else{
        *map[argv[0]];
    }
}

由于

- 编辑 -

只是提供更多信息:

这个问题的原因是我正在为现有的应用程序实现一个下拉式“quake-style”控制台。这样我就可以提供运行时命令行用户输入来访问各种类型的已编码函数,即:

 /exec <functionName> <param1> <param2> ...

5 个答案:

答案 0 :(得分:3)

如果你想要“指向某个东西,但我不打算定义什么,而且它可能是各种各样的东西”,你可以使用void *

但你真的不应该。

void *纯粹是一个指针。为了对它做任何事情,你必须将它转换为更有意义的指针,但在那时,你已经失去了所有类型的安全性。什么阻止某人使用错误的功能签名?或者使用指向结构的指针?

修改

为了给你一个更有用的答案,没有必要把这一切都放在一张地图上。可以使用多个地图。即。

typedef boost::function<void(void)> voidFunctionPointer;
typedef boost::function<int(int)>   intFunctionPointer;

map<std::string, voidFunctionPointer> _myVoidMap;
map<std::string, intFunctionPointer > _myIntMap;

void CreateFunctionMap()
{
  _myVoidMap["functionA"] = &functionA;
  _myIntMap["functionB"] = &functionB;
  ...
}

void execute(int argc, char* argv[])
{

  if(argc>1){
    int param = atoi(argv[1]);
    int answer;
    // todo: check that argv[0] is actually in the map
    intFunctionPointer mfp = _myIntMap[argv[0]];
    answer = mfp(param);
  }
  else{
    // todo: check that argv[0] is actually in the map
    voidFunctionPointer mfp = _myVoidMap[argv[0]];
    mfp();
  }
}

答案 1 :(得分:3)

您可以使用

boost::variant<
    boost::function<void(void)>,
    boost::function<void(int)> >

答案 2 :(得分:2)

为什么不添加int (*func)(int argc, char* argv[])类型的函数?您可以轻松地从execute的参数中删除第一个参数并调用相关参数。

答案 3 :(得分:2)

您是否可以使用命令模式来封装函数调用。因此,您可以将函数存储在仿函数中,并在病房之后调用它们。对于functor实现,您可以查看Andrei Alexandrescu的Modern C ++ Design。

答案 4 :(得分:1)

您的每个函数都有不同的类型,因此您需要某种类型的擦除。你可以使用它们中最通用的:Boost.Any。您可以拥有map boost::any,但您需要知道该函数的类型才能将其恢复并调用它。

或者,如果您提前知道自己的论点,可以使用函数调用bind并使地图中的所有函数都为无效函数:function< void() >。即使你不这样做,你也可以通过将参数绑定到引用来逃脱它,然后在调用时用适当的参数填充引用的变量。