如何从C 中的另一个模板函数重新铸造模板函数
How to re-cast a templated function from another templated function in C++
我正在为普通微分方程(ODE(编写一个求解器,并且正在尝试实现运行的时间行为,该行为允许用户从多个ode solvers(例如forward euler方法(中进行选择,第二个和第四阶runge-kutta方法。我正在努力使用一组模板功能,以便用户可以将变量作为映射传递给求解器,其中键可以是int
,char
或std::string
。另外,关联的值可以是float
或double
。在标题为ode_solver()
的会员功能中,我需要设置变量class_func
等于求解器函数之一,即 euler_method
, rk2_method
或 rk4_method
;但是,由于这些功能没有模板,因此我会收到Variable 'class_func' with type auto has incompatible initializer of type <overloaded>
的消息。我敢肯定,这是由于C 不允许我动态分配一种类型。代码如下提供。有没有办法启用我在此问题中尝试的行为,还是我不得不放弃模板并仅将数据类型进行编码?.HPP文件中的所有大写字母中突出显示了代码出现问题的区域。我正在使用C 17编译器。
// main.cpp
#include "test.hpp"
#include <iostream>
#include <math.h>
#include <map>
#include <tuple>
double func6(std::map<char, double> arr);
int main(int argc, const char * argv[]) {
ODESolver q;
// Code inputs
std::map<char, double> inputs;
inputs['x'] = 2.0;
inputs['y'] = g.e;
double unc = 0.001;
double tol = 0.0;
double step_size = 0.1;
double start = 2.0;
double stop = 3.0;
std::string func_name("Euler");
std::tuple<std::vector<double>, std::vector<double>> res;
res = q.new_ode_solver(step_size, start, stop, tol, func_name,
inputs, func6);
}
double func6(std::map<char, double> arr)
{
return arr['y'] * MathKernels::logr(arr['y']) / arr['x'];
}
标题文件是
class ODESolver
{
public:
template<class char_type, class real_type, class F>
static inline std::tuple<std::vector<real_type>, std::vector<real_type>>
ode_solver(real_type step_size, real_type start, real_type stop,
real_type error, std::string func_name,
std::map<char_type, real_type> &inputs,
const F& func)
{
// Verify that a correct function name was passed
if (func_name != "Euler" and func_name != "RK2" and func_name != "RK4")
{
std::cout << "FATAL ERROR: ODE Solver Name must be 'Euler', 'RK2' or 'RK4'" << std::endl;
exit (EXIT_FAILURE);
}
// Determine which ODE Solver to use
// - THIS IS THE PROBLEM, THE COMPILER CANNOT DEDUCE
// THE TYPE FROM THE STATEMENT BELOW.
auto class_func = &ODESolver::euler_method;
std::tuple<real_type, real_type> res;
std::vector<char_type> keys;
std::vector<real_type> x_var;
std::vector<real_type> y_var;
keys = get_keys(inputs);
std::cout << keys[0] << std::endl;
// Solve ODE
x_var.push_back(inputs[keys[0]]);
y_var.push_back(inputs[keys[1]]);
real_type time = start;
while (time < stop)
{
res = class_func(func, step_size, inputs, keys, error);
y_var.push_back(std::get<0>(res));
step_size = std::get<1>(res);
x_var.push_back(time);
time += step_size;
inputs[keys[0]] += step_size;
inputs[keys[1]] = std::get<0>(res);
}
std::tuple<std::vector<real_type>, std::vector<real_type>> value(x_var, y_var);
return value;
}
// ================================================================
template<class char_type, class real_type, class F>
static inline std::tuple<real_type, real_type>
euler_method(real_type step_size, std::map<char_type, real_type> inputs,
real_type keys, real_type error,
const F& func)
{
real_type dydx = func(inputs);
real_type value = inputs[keys[1]] + step_size * dydx;
std::tuple<real_type, real_type> vals(value, step_size);
return vals;
}
// ================================================================
// ================================================================
private:
template<class char_type, class real_type>
static inline std::vector<char_type> get_keys(std::map<char_type, real_type> &arr)
{
std::vector<char_type> keys;
for (typename std::map<char_type, real_type>::iterator it = arr.begin();
it != arr.end(); it++)
{
keys.push_back(it -> first);
}
return keys;
}
};
正如其他提到的您正在尝试存储函数的地址,但分配无法分配函数模板的地址!
只需指定模板参数,并且由于ode_solver
功能模板中已经存在这些参数(除非不需要这样做(,您可以直接在euler_method
函数模板中使用它们。快速修复看起来像:
auto class_func = &ODESolver::euler_method<char_type, real_type, F>;
也在同一类中:
auto class_func = &euler_method<char_type, real_type, F>;
祝你好运!
相关文章:
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- C++模板函数中的初始化 - 新的初始值设定项表达式列表被视为复合表达式
- 是什么让放置新调用对象的构造函数?
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 新分配指向函数的指针是否合法?
- 放置上的析构函数 - 新
- 将新放置与 std::函数一起使用不起作用
- 静态堆栈函数不会 1) 输入第一个元素 2)添加新元素时识别旧元素
- 如何在C++中将构造函数的新输入推回构造函数的默认输入?
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- 从使用概念定义的函数返回新对象
- 当我从 std::vector 中的新放置调用析构函数时会发生什么?
- 如何访问子类的新成员函数?
- 如何在 main 函数中输出两个新字符串C++?
- C++类析构函数使用新值而不是实际值
- 我可以动态创建新地图并作为函数参数传递吗?
- 如何从C 中的另一个模板函数重新铸造模板函数
- OPENCV C 调整大小函数:新宽度应乘以3
- 预期的"("用于函数式铸造或类型构造
- C++:构造函数:新实例中的父类参数和设置值