简体   繁体   English

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

[英]C++: std::vector of function template pointers

The idea is to call similar Runge-Kutta function templates in a loop instead of doing it one by one. 这个想法是要循环调用类似的Runge-Kutta函数模板,而不是一个接一个地进行。 I've looked at similar solutions , I also tried void* , but was not able to apply to my problem due to conversion errors. 我看过类似的解决方案 ,我也尝试过void* ,但由于转换错误而无法解决我的问题。

EDIT: these function templates are supposed to be used with fixed types, it's an overkill, but I would like to see whether there is an elegant solution. 编辑:这些功能模板应该与固定类型一起使用,这是一个过大的杀伤力,但我想看看是否有一个优雅的解决方案。

Here is the full code: 这是完整的代码:

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

What I would like to have (the actual algorithm is simplified for the sake of readability): 我想拥有的(为了易于阅读,简化了实际算法):

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

You can not have a pointer to a function template. 您没有指向功能模板的指针。 You can only have a pointer to specific instantiation of the template. 您只能有一个指向模板的特定实例的指针。 In a same manner, you can't pack a template into std::function - only a specific instantiation of it. 以同样的方式,您不能将模板打包到std::function -只能打包模板的特定实例。

And you can only put objects of the same type in the container - so your pointers will have to be of the same type (ie the function they point to should accept the same type of arguments and return the same type). 而且,您只能将相同类型的对象放入容器中-因此您的指针将必须具有相同的类型(即,它们指向的函数应接受相同类型的参数并返回相同类型)。

std::function will have the same limitation - all std::functions inside the container must be of the same type, in terms of return value and arguments. std::function将具有相同的限制-就返回值和参数而言,容器内的所有std::functions必须具有相同的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM