C++ C++;:函数模板指针的向量
其思想是在循环中调用类似的Runge-Kutta函数模板,而不是逐个调用。我研究过类似的问题,我也尝试过C++ C++;:函数模板指针的向量,c++,templates,C++,Templates,其思想是在循环中调用类似的Runge-Kutta函数模板,而不是逐个调用。我研究过类似的问题,我也尝试过void*,但由于转换错误,无法应用于我的问题 编辑:这些函数模板应该与固定的类型一起使用,这有些过分,但我想看看是否有一个优雅的解决方案 以下是完整的代码: #include <iostream> #include <iomanip> #include <cmath> #include <functional> template <ty
void*
,但由于转换错误,无法应用于我的问题
编辑:这些函数模板应该与固定的类型一起使用,这有些过分,但我想看看是否有一个优雅的解决方案
以下是完整的代码:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <functional>
template <typename X, typename F, typename H = double>
X runge_kutta1(const X &x, const F &f, H h)
{
return x + h * f(x);
}
template <typename X, typename F, typename H = double>
X runge_kutta2(const X &x, const F &f, H h)
{
X k1 = f(x);
return x + 0.5 * h * (k1 + f(x + h * k1));
}
struct pair
{
double v;
double w;
pair(double v, double w)
: v{v}, w{w}
{
}
};
inline pair operator*(double h, pair p)
{
return {h * p.v, h * p.w};
}
inline pair operator+(pair p1, pair p2)
{
return {p1.v + p2.v, p1.w + p2.w};
}
inline std::ostream &operator<<(std::ostream &stream, const pair &p)
{
stream << p.v << ", " << p.w;
return stream;
}
int main() {
{
double x = 0.0;
double x1 = 1.0;
double lambda = 2;
double h = 1.0E-3;
pair p{1.0 / lambda, 0.0};
const std::function<pair(pair)> cat =
[&lambda](const pair &p) { return pair{p.w, lambda * sqrt(1.0 + p.w * p.w)}; };
while (x + h < x1)
{
p = runge_kutta1(p, cat, h);
x = x + h;
}
p = runge_kutta1(p, cat, x1 - x);
pair expected = {cosh(lambda * x1) / lambda, sinh(lambda * x1)};
pair error = p + -1.0 * expected;
std::cout << std::setprecision(18) << "runge_kutta1:\nFinal result: " << p << "\n";
std::cout << "Error: " << error << "\n\n";
}
{
double x = 0.0;
double x1 = 1.0;
double lambda = 2;
double h = 1.0E-3;
pair p{1.0 / lambda, 0.0};
const std::function<pair(pair)> cat =
[&lambda](const pair &p) { return pair{p.w, lambda * sqrt(1.0 + p.w * p.w)}; };
while (x + h < x1)
{
p = runge_kutta2(p, cat, h);
x = x + h;
}
p = runge_kutta2(p, cat, x1 - x);
pair expected = {cosh(lambda * x1) / lambda, sinh(lambda * x1)};
pair error = p + -1.0 * expected;
std::cout << "runge_kutta2:\nFinal result: " << p << "\n";
std::cout << "Error: " << error << "\n";
}
}
#包括
#包括
#包括
#包括
模板
X runge_kutta1(常数X&X,常数F&F,H)
{
返回x+h*f(x);
}
模板
X runge_kutta2(常数X&X,常数F&F,H)
{
xk1=f(X);
返回x+0.5*h*(k1+f(x+h*k1));
}
结构对
{
双v;
双w;
成对(双v,双w)
:v{v},w{w}
{
}
};
内联对运算符*(双h,对p)
{
返回{h*p.v,h*p.w};
}
内联对运算符+(对p1,对p2)
{
返回{p1.v+p2.v,p1.w+p2.w};
}
内联std::ostream&operator您不能有指向函数模板的指针。您只能有一个指向模板的特定实例化的指针。以同样的方式,您不能将模板打包到std::function
——只能将它的特定实例化
并且您只能将相同类型的对象放入容器中,因此您的指针必须是相同类型的(即,它们指向的函数应该接受相同类型的参数并返回相同类型的参数)
std::function
将具有相同的限制-容器中的所有std::functions
在返回值和参数方面必须是相同的类型 不能有指向函数模板的指针。您只能有一个指向模板的特定实例化的指针。以同样的方式,您不能将模板打包到std::function
——只能将它的特定实例化
并且您只能将相同类型的对象放入容器中,因此您的指针必须是相同类型的(即,它们指向的函数应该接受相同类型的参数并返回相同类型的参数)
std::function
将具有相同的限制-容器中的所有std::functions
在返回值和参数方面必须是相同的类型 模板不是值。因此,你的解决方案是错误的,它将一事无成。您需要备份并重新构造问题,而不是试图用“模板向量”来解决它。向量存储值,模板不是值。@Yakk AdamNevraumont我宁愿说模板不是类型,而不是值-在我看来,它更清楚int
不是一个值,但是int
s的向量确实存在。@Yakk AdamNevraumont,我知道了,有没有办法实例化一个模板并在std::vector中使用它?至少在这个问题上,所有的实例都有相同的类型。老实说,根本不需要提到Runge Kutta。您的目标是以某种容器化的方式调用一组模板函数。“没有必要向我们展示数学计算来简单地说明这一点。”米哈伊尔·克拉萨文当然可以,但它将指向它的一个特定版本。它只适用于指定的参数类型。模板不是值。因此,你的解决方案是错误的,它将一事无成。您需要备份并重新构造问题,而不是试图用“模板向量”来解决它。向量存储值,模板不是值。@Yakk AdamNevraumont我宁愿说模板不是类型,而不是值-在我看来,它更清楚int
不是一个值,但是int
s的向量确实存在。@Yakk AdamNevraumont,我知道了,有没有办法实例化一个模板并在std::vector中使用它?至少在这个问题上,所有的实例都有相同的类型。老实说,根本不需要提到Runge Kutta。您的目标是以某种容器化的方式调用一组模板函数。“没有必要向我们展示数学计算来简单地说明这一点。”米哈伊尔·克拉萨文当然可以,但它将指向它的一个特定版本。它只适用于指定的参数类型。
std::vector<?> functions{runge_kutta1, runge_kutta2}; // two just as an example
double p = 1.0;
double h = 1.0E-3;
double lambda = 2;
const std::function<pair(pair)> cat =
[&lambda](const pair &p) { return pair{p.w, lambda * sqrt(1.0 + p.w * p.w)}; };
for (const auto& func : functions) {
double t = func(p, cat, h);
std::cout << t << "\n";
}