【问题标题】:Generic function implementation in C++C++ 中的泛型函数实现
【发布时间】:2012-10-03 05:33:37
【问题描述】:

我正在开发一个新平台,我的代码是:

第 1 层:

Call_To_Layer2 (param1, param2);

第二层:

Call_To_Layer2(param1, param2)
{
    Dispatch_Work_To_Thread(param1, param2);
}

Dispatch_Work_To_Thread(param1, param2)
{
    // create a new thread and execute the task
}

来自 Layer1 的函数调用可以有任意数量的参数。那么如何在 Layer2 中设计这样的方法呢? layer2 中的 Dispatch_Work_To_Thread 方法需要函数名作为参数之一。既然参数个数不固定,那怎么设计呢?

我一直在思考这个问题的设计,但直到现在都没有想出任何解决方案。

【问题讨论】:

  • 我不太清楚它会有多大帮助,但我有一些工作可以使用传入的参数调用任何函数(例如 wrap(std::pow, 2.5, 3); 之类的东西)。整个void 业务是这样的,只有当它有返回值时我才能存储它。无论如何,stackoverflow.com/questions/9625526/…

标签: c++


【解决方案1】:

一种选择是让Call_To_Layer2Dispatch_Work_To_Thread 采用std::function<void(void)>,并使用任何函数名称和参数创建函数对象。

Layer1 功能:

void foo_layer1(param1, param2);
void bar_layer1(param1, param2);

第 2 层:

#include <functional>

Call_To_Layer2 (std::function<void(void)> f); // or reference_wrapper to std::function

f00 = std::bind(foo_layer1, param1, param2);
Call_To_Layer2(foo);  // passes it on to `Dispatch_Work_To_Thread`

如果您没有所需的 C++11 支持,您可以改用 boost.functionboost.bind

【讨论】:

    【解决方案2】:
    1. 也许把所有的参数放在一个结构体或一个类中,然后将一个对象传递给Call_To_Layer2?如果类可以封装变量因子,这将起作用。

    2. 另一种选择是使用可变参数函数语法Call_To_Layer2(param1, param2, ...)

    【讨论】:

      【解决方案3】:

      如果没有更具体的示例,很难知道最佳解决方案是什么。

      Variadic functions 可能是一种选择,尽管如今它们大多被认为是过时的。

      最简单的方法可能是将参数简单地包装在 std::vector 或类似名称中,然后让第 2 层代码根据需要将它们解包。

      【讨论】:

        【解决方案4】:

        这不是 C++ 可移植的。但是,您可以稍作更改,让您的函数接受一个参数,该参数是一个包含所有相关参数的映射:

        typedef std::map<std::string, Anything> Parms;
        
        Anything function1(const Parms& parms)
        {
            double x = parms("x");
            std::string title = parms("title");
            ...
        }
        
        void init_module()
        {
            register_function("function1", function1,
                              "void return, double x, string title");
        }
        

        在上面的示例中,Anything 是一个类,它可以包含您想要支持的任何类型作为参数或返回值。我习惯于自己编写代码,但可能boost::any 可以。 每个发布的函数只接受一个参数字典,并且该函数还发布返回类型和参数。此信息存储在映射中,用于调度和参数检查,因此您无需对所有函数进行代码检查,还允许发布目录服务。

        您还可以使用实现“调用”方法的类的实例,而不是发布服务的函数(这是我习惯做的)。

        不幸的是,C++ 设计与此用例不太兼容,需要大量编码。在运行时提供函数名称和参数的情况下,没有像“使用此名称调用函数并传递这些参数”这样的事情。

        请注意,另一方面,这种用法并不少见,因此您可以找到许多试图将这种动态性添加到 C++ 的库......它们如何适合您的确切问题,它们有什么依赖关系以及有多复杂他们是必须考虑的事情。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-08
          • 1970-01-01
          • 2023-04-04
          • 1970-01-01
          相关资源
          最近更新 更多