0

想象一下,我想编写一个函数来处理两个函数的值(例如比较)。

f1 和 f2 是示例,但它应该适用于更多功能,与参数的数量和类型无关。

double f1 (double x, double y, double z) {
    return pow(x,3)+2*pow(y,2)+3*z;
}

double f2 (std::vector<double> vec) {
    double result;
    for (int i=0; i<vec.size(); i++){
        result += vec[i];
    }
    return result;
}

现在我想要一个可以像这样(或类似)调用的比较函数:

int main() {
    std::vector<double> example_vector {1,3,3,7};
    compare(f1, {4, 5, 6}, f2, example_vector);
    return 0
}

在里面比较它会调用 f1 与 x=4、y=5、z=6 和 f2 与 vec=example_vector。

编辑:

这是我最后使用的解决方案:

#include <iostream>
#include <tuple>
#include <utility>
#include <math.h>
#include <vector>

template<typename FuncA, typename FuncB, typename ...FA_Params, typename ...FB_Params>
void do_sth(FuncA &func_a, FuncB &func_b, const std::tuple<FA_Params ...> &a_params, const std::tuple<FB_Params ...> &b_params) {
    std::cout << std::apply(func_a, a_params) << std::endl;
    std::cout << std::apply(func_b, b_params) << std::endl;
}

//f1, f2 and f3 are example functions

double f1 (double x, double y, double z) {
    return pow(x,3)+2*pow(y,2)+3*z;
}

double f2 (std::vector<double> vec) {
    double result;
    for (int i=0; i<vec.size(); i++){
        result += vec[i];
    }
    return result;
}

double f3 (double a, double omega, double t, double delta) {
    double result;
    result = a*sin(omega*t+delta);
}

int main() {
    do_sth(f1, f2, std::make_tuple(1.0, 2.3, 1.3), std::make_tuple(std::vector<double>{1.0, 2, 3}));
    return 0;
}

C++20 对我还不起作用,这只需要 C++17。

do_sth 应该能够采取任何功能

4

1 回答 1

0

我在这里看不到目标,所以很难让它成为一个通用的解决方案,但基本上你可以做这样的事情:

template<typename FuncA, typename FuncB>
void compare(FuncA func_a, const std::vector<double> &vec_a, FuncB func_b, const std::vector<double> &vec_b) {
    double res1 = func_a(vec_a[0], vec_a[1], vec_a[2]);
    double res2 = func_b(vec_b);
    // Do something...
}

可能有更通用的解决方案来做你想做的事,但你必须明确你的目标。

顺便说一句,关于f2

double f2(std::vector<double> vec);

您可以通过引用/常量引用传递向量以避免数据复制:

double f2(const std::vector<double> &vec);

编辑 - 使用可变参数函数求解

更通用的方法可能是:
template<typename FuncA, typename FuncB, typename FB_Param, typename ...FA_Params>
void compare(FuncA func_a, FuncB func_b, FB_Param b_param, FA_Params ...a_params) {
    func_a(a_params...);
    func_b(b_param);
}

调用可能如下所示:

compare(f1, f2, std::vector<double>{1.0, 2, 3}, 1.0, 2.3, 1.3);

但要注意的最重要的事情是,您不能在同一个函数中组合两个可变参数,因此您传递给此函数的函数之一应该接受单个参数(在本例中为 func_b)。


编辑 - 使用 std::apply 支持解决

正如@fT3g0将元组用于多个值的想法,这是我的 c++20 版本: Pass params as std::tuples/std::arrays/std::pair/anything that support std::apply implementation

template<typename Type>
concept ApplySupporter =
    requires (Type t) {
        { std::get<std::tuple_size<Type>() - 1>(t) };
        { std::tuple_size<Type>() };
    };

template<typename FuncA, ApplySupporter FA_Params, typename FuncB, ApplySupporter FB_Params>
void compare(FuncA func_a, FA_Params a_params, FuncB func_b, FB_Params b_params) {
    std::cout << std::apply(func_a, a_params) << std::endl;
    std::cout << std::apply(func_b, b_params) << std::endl;
}

阅读

std::apply
概念
std::get
std::tuple_size

于 2020-06-20T22:12:45.483 回答