Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将多个函数传递给C+中向量内的另一个函数+;_C++_C++17 - Fatal编程技术网

C++ 将多个函数传递给C+中向量内的另一个函数+;

C++ 将多个函数传递给C+中向量内的另一个函数+;,c++,c++17,C++,C++17,我正在尝试为耦合常微分方程编写一个解算器,这将需要我将多个函数传递给解算器函数。其思想是,用户可以在主文件中编写耦合的ODE函数,调用框架头文件,并将其函数传递给框架以求解ODE 在某些情况下可能只有两个功能,在其他情况下可能有三个、四个或更多功能。我试图通过将耦合函数封装在一个向量中来实现这一点,我希望在这个过程中调用std::function包装器。下面我展示了一个类似代码的简化版本。目前,我正在尝试定义一种将函数封装在数组中的方法,以便将其传递给解算器函数。我使用的是C++17编译器。有没

我正在尝试为耦合常微分方程编写一个解算器,这将需要我将多个函数传递给解算器函数。其思想是,用户可以在主文件中编写耦合的ODE函数,调用框架头文件,并将其函数传递给框架以求解ODE

在某些情况下可能只有两个功能,在其他情况下可能有三个、四个或更多功能。我试图通过将耦合函数封装在一个向量中来实现这一点,我希望在这个过程中调用std::function包装器。下面我展示了一个类似代码的简化版本。目前,我正在尝试定义一种将函数封装在数组中的方法,以便将其传递给
解算器
函数。我使用的是C++17编译器。有没有一种方法可以在数组中传递这些函数,或者有没有一种我不知道的更好的方法

double func1(std::map<std::string, double> arr)
{
    dydt = arr["one"] * 3.0 - arr["two"];
    return dydt;
}

double func2(std::map<std::string, double> arr)
{
    dydt = 1 / arr["three"] + 3.0 * arr["two"];
    return dydt;
}

double solver(std::vector<std::function<double(std::map<std::string, double>) &funcs, std::map<std::string, double> inputs)
{
    double res;
    std::vector<double> data;
    for (int i = 0; i < funcs.size(); i++)
    {
        // - The ODE solver is not shown in this example, 
        //   but it highlights the general intent
        res = funcs[i](inputs);
        data.push_back(res);
    }
    return data;
}

int main()
{
    std::map<std::string, double> inputs;
    inputs["one"] = 1.0;
    inputs["two"] = 2.0;
    inputs["three"] = 3.0;
    inputs["four"] = 4.0;

    // The line of code below does not work
    std::vector<std::function<double(std::map<std::string, double>)>> funcs = {func1, func2};
    std::vector<double> dat;

    // - Due to the fact that the array of funcs does not work, 
    //  this function call also does not work
    dat = solver(funcs, inputs);
    return 0;
}
double func1(标准::映射arr)
{
dydt=arr[“一”]*3.0-arr[“两”];
返回dydt;
}
双功能2(标准::映射arr)
{
dydt=1/arr[“三”]+3.0*arr[“两”];
返回dydt;
}

双解算器(std::vector您可以通过混合使用
std::function
std::any
和参数包来实现这一点:

#include <functional>
#include <string>
#include <map>
#include <any>
#include <vector>

using my_f_type = std::function<int(std::map<std::string, int>&)>;

template<typename...T>
int solver(const T& ... functions) {
    std::vector<std::any> vec = { functions... };
    std::map<std::string, int> foo = { { "test", 37 } };
    for (auto& f : vec) {
        try {
            return std::any_cast<my_f_type>(f)(foo);
        } catch (const std::bad_any_cast& e) {}
    }
    return 0;
}

int main() {
    std::function<int(int)> a = [](int a) { return a; };
    std::function<double(double)> b = [](double b) {return b; };
    my_f_type c = [](std::map<std::string, int>& c) { return c["test"]; };
    return solver(a, b, c);
}

由于您将问题标记为C++17,因此可以使用带有以下内容的可变函数模板:

现在,您不再需要向量来传递函数。您可以直接将它们作为参数传递给
解算器

int main()
{
    std::map<std::string, double> inputs {
        {"one", 1.0},
        {"two", 2.0},
        {"three", 3.0},
        {"four", 4.0}
    };

    auto results = solver(inputs, func1, func2);
}

(您可以使用
const std::map&arr
而不是
auto-arr
,如果您更易于阅读。请注意,lambda中的
auto
表示lambda成为模板。)

您的
std::function
使用
std::map
但您尝试放入其中的函数使用
std::map
。编译器会告诉您一些其他的排版错误。一旦我修复了这些排版错误,代码就会编译。@Raymond Chen,您是对的,我刚刚编辑了示例以补充用std::string将字符转换为ace;但是,它仍然不起作用。我收到一条消息说,
无匹配构造函数
。希望今晚我能有机会实现它。如果它适合我的需要,我会让你知道。不管怎样,我肯定从你的回复中学到了一些东西,所以我很感激。非常小的改变我明白了,我不能使映射保持不变,因为其中一些变量将在ODE解算器的每个时间步更新。您的回答回答回答了我的问题,因此我将把它标记为答案。但是,我没有问正确的问题,所以它没有回答我的真实问题。我将重新发布;但是,一般来说,有办法吗要从折叠表达式中解析出每个函数,我需要在循环中遍历每个函数,并将每个函数传递给另一个函数,在下一个函数使用
inputs
映射之前,它将修改
inputs
的值。
template<typename ...Funcs>
std::vector<double> solver(const std::map<std::string, double>& inputs, Funcs&&... funcs)
{
    std::vector<double> results;
    (results.push_back(funcs(inputs)), ...);
    return results;
}
double func1(const std::map<std::string, double>& arr);
int main()
{
    std::map<std::string, double> inputs {
        {"one", 1.0},
        {"two", 2.0},
        {"three", 3.0},
        {"four", 4.0}
    };

    auto results = solver(inputs, func1, func2);
}
solver(inputs,
    [](auto arr){ return arr["one"] * 3.0 - arr["two"]; },
    [](auto arr){ return 1 / arr["three"] + 3.0 * arr["two"]; }
);