映射到具有不同数量参数和不同数据类型的函数指针

map to a function pointer with different number of arguments and varying datatypes

在我的代码中,我有几个 class,每个都有不同的方法。例如:

class A {
public:
    int sum(int a, int b);
    bool isScalable(double d);
}

class B {
public:
    std:string ownerName();
}

我的目标是创建一个所有函数名称的映射,如下所示

std::map<std::string, FnPtr> myMap;

// Add the newly implemented function to this map
myMap["sum"] = &A::sum;
myMap["isScalable"] = &A::isScalable;
myMap["myMap"] = &B::myMap;

问题是我不知道如何定义 FnPtr。你能帮帮我吗

如评论所述,您不太可能真的想要这样做。

但是,假设您这样做了 - 也许您应该重新考虑 C++ 是否是完成该任务的正确语言。另一种具有更好的运行时反射功能的语言可能更合适;也许是像 Python 或 Perl 这样的解释性语言。当您需要在运行时按名称查找 class 方法时,这些通常要方便得多。

如果它必须是 C++,那么也许您应该稍微放宽 class 结构。对 A 和 B 使用单个 class(我们称之为 MyCommonObj);并让 class 保存一个字符串映射到函数指针。至于这些函数的签名——最好不要创建成员函数,而是创建独立函数。在这种情况下,您的函数指针类型可能是:

using generic_function = std::any (*)(std::vector<std::any>);

这非常通用 - 用于存储和调用。如果您有此映射,则可以轻松查找您的函数名称并传递参数。但是,您可能还需要保留有关参数类型的其他信息,否则您将始终传递字符串。 ...这也是一种选择,我想:

using generic_function = std::any (*)(std::vector<std::string>);

现在,如果您的示例中的 A 和 B 成员确实 non-static 就像您列出的那样,即它们使用实例字段,那么这些通用函数也必须始终采用指向 non-static 的实例的引用或指针=13=]:

using generic_function = std::any (*)(MyCommonObj&, std::vector<std::string>);

最后,请注意使用此类型的代码以及 run-time 查找函数名称等 - 性能不会很好。


如果您没有使用 C++17 并且无法访问 std::any,您可以:

  • 使用来自 Boost 库的 boost::any
  • 使用 any-emulator 库(存在于 GitHub)
  • 使用您实际使用的所有类型的联合,例如union {int i; double d;} - 但是你需要保护自己免受传递错误类型的值的影响。