c++ - 我可以从 C++17 折叠表达式中解析出单个函数吗

标签 c++ templates c++17 variadic-templates

我正在尝试编写一个代码来求解耦合常微分方程(即 ODE)。该函数需要接受一个函数数组,每个函数都是耦合的 ODE 之一。我正在尝试使用 C++17 折叠表达式将函数传递给主函数,然后主函数将函数单独传递给求解器,一次一个。求解器需要求解方程,并根据结果修改输入 map 。映射必须根据第一个函数的结果进行修改,因为修改后的映射是下一个函数的输入。通用代码如下所示。代码已简化以突出显示我试图解决的问题。

int main()
{
    ODESolver q;
    std::map<std::string, double> inputs {
        {"x", 1.0},
        {"y", 2.0},
        {"z", 3.0},
        {"a", 4.0}
    };

    auto results = solver(inputs, func1, func2);
}

double func1(std::map<std::string, double> arr)
{
    double dcadt = -arr["x"] * arr["y"] + arr["z"] * arr["a"];
    return dcadt;
}

double func2(std::map<std::string, double> arr)
{
    double dccdt = arr["x"] * arr["y"] - arr["a"] * arr["z"];
    return dccdt;
}

类中的信息显示在这里;

class ODESolver
{
public:
    template<typename ...Funcs>
    std::vector<double> framework(std::map<std::string, double> inputs, Funcs&&... funcs)
    {
        std::tuple<double, double> res;
        for (int i = 0; i < funcs.size(); i++)
        {
            // - THIS IS WHERE MY PROBLEM IS MANIFESTED, THE
            //   COMPILER WILL NOT LET ME EXTRACT AN INDIVIDUAL
            //   FUNCTION FROM A FOLD EXPRESSION!
            res = solver(inputs, funcs[i]);
            step_size = std::get<1>(res);
            inputs["x"] += 1.0;
            inputs["y"] std::get<0>(res);
        }
    }
    std::tuple<double, double>
    ODESolver::solver(std::map<std::string, double>, const std::function<double(std::map<std::string, double>)& func)
    {
        double dydt = func(inputs);
        double val = inputs["y"];
        std::tuple<double, double> values(dydt, val);
        return values;
    }
};

上面的例子有些虚构,但它突出了我实际代码的问题。我不知道如何从 C++17 折叠表达式中提取单个函数,因此我可以将它们单独传递给另一个函数。从上面的代码可以看出,我需要先解决func1,这样它才能在func2使用之前更新inputs映射inputs 在其函数调用中。有没有一种方法可以使用折叠表达式执行此操作,或者是否有另一种方法需要将函数从主程序传递到 framework 函数。

最佳答案

写一个 lambda 来做你需要做的事情:

auto apply_next = [&](auto&& f){
    res = solver(inputs, f);
    step_size = std::get<1>(res);
    inputs["x"] += 1.0;
    inputs["y"] += std::get<0>(res);
};

然后将 lambda 调用折叠在逗号上:

(apply_next(funcs), ...);

Expansion Statements看起来 C++20 正步入正轨,这将允许您开始编写更直接的内容:

for ... (auto&& f : funcs) {
    res = solver(inputs, f);
    step_size = std::get<1>(res);
    inputs["x"] += 1.0;
    inputs["y"] += std::get<0>(res);
}

关于c++ - 我可以从 C++17 折叠表达式中解析出单个函数吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56295919/

相关文章:

c++ - 为什么min仍然在constexpr中提示?

c++ - 访问 range_expression 内的嵌套元素返回不完整的映射(段错误)

c++ - 打开 CV 延迟测量

c++ - 优化二进制增量循环

c++ - 虚函数和默认参数

c++ - #define 值在单独的文件中,它将如何影响编译?

具有灵活返回类型的 C++ 函数模板

c++ - 依赖模板名称和 C++20 ADL

c++ - [[nodiscard]] 属性 : By default? 的指南仅在某些误用检测的情况下?

c++ - 关于不完整类型的 SFINAE 的特殊规则