【问题标题】:map to a function pointer with different number of arguments and varying datatypes映射到具有不同数量参数和不同数据类型的函数指针
【发布时间】:2020-08-06 07:17:27
【问题描述】:

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

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。你能帮帮我吗?

【问题讨论】:

  • 你想达到什么目的?您可以使用void * 作为类型并根据需要进行强制转换,但这通常是个坏主意。可能有更好的方法来解决您的潜在问题。
  • @BennyK:我想将每个函数映射到一个字符串。这是因为有来自应用程序外部的字符串格式的消息,我需要根据字符串调用函数。例如。调用sum(10,15),收到的消息是“sum 10 15”
  • 见:this question。您可能不想这样做,调用这些函数中的任何一个都非常脆弱。
  • 很难想出一个合理的方案来解决问题
  • 只需在第一个单词上使用 switch case。 Switch 至少应该和 std::map 一样快。

标签: c++ c++11 templates function-pointers


【解决方案1】:

正如 cmets 所建议的,您不太可能真的想要这样做。

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

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

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

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

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

现在,如果您的示例中的 A 和 B 成员真的像您列出的那样是非静态的,即它们使用实例字段,那么这些通用函数也必须始终采用指向 MyCommonObj 实例的引用或指针:

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

最后,请注意使用这种类型的代码,以及函数名的运行时查找等 - 性能不会很好。


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

  • 使用 Boost 库中的 boost::any
  • 使用任意模拟器库(GitHub 上存在)
  • 使用您实际使用的所有类型的并集,例如union {int i; double d;} - 但是你需要保护自己免受错误类型的值的传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-26
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    相关资源
    最近更新 更多