C ++:函数模板指针的std :: vector

时间:2018-11-16 18:51:52

标签: c++ templates

这个想法是循环调用类似的Runge-Kutta函数模板,而不是一个接一个地进行。我看过类似的solutions,也尝试过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";
    }
}

我想要拥有什么(为了易于阅读,简化了实际算法):

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";
}

1 个答案:

答案 0 :(得分:2)

您不能具有指向功能模板的指针。您只能有一个指向模板的特定实例的指针。同样,您不能将模板打包到std::function中,而只能打包模板的特定实例。

而且您只能将相同类型的对象放入容器中-因此您的指针将必须具有相同类型(即,它们指向的函数应接受相同类型的参数并返回相同类型)。 / p>

std::function将具有相同的限制-就返回值和参数而言,容器内的所有std::functions必须具有相同的类型。