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