如何使用 std::function 接受具有不同参数的函数?

问题描述 投票:0回答:2

我有 2 个函数,

first_function
second_function
具有相似的签名。
second_function
需要2个额外的参数,
x, y
.

我想创建另一个可以将

first_function
second_function
作为参数的函数。

我正在考虑使用

std::function
,但似乎仅限于具有相同返回类型和相同参数的输入函数?有没有办法让它适用于我的情况?

这是我想要实现的最小示例:

void first_function(double z) {
  // Implementation not included
}

void second_function(double x, double y, double z) {
  // Implementation not included
}

void compute(first_or_second_function, std::optional<double> x, std::optional<double> y, double z) {

  if (x.has_value()) {
    // invoke second function
    first_or_second_function(x.value, y.value(), z);
  } else {
    // invoke first function
    first_or_second_function(z);
  }

}

我不确定如何创建参数

first_or_second_function

c++ std-function
2个回答
0
投票

我有点不确定为什么要将它传递给函数并让函数决定而不是在您提供的 if 语句中自行调用每个函数。

我相信您正在寻找的代码是这样的:

#include <iostream>
using namespace std; // Shouldn't use this, only for example purposes.

template<typename... Args>
void myFunc(Args... args) {
  cout << "myFunc called with " << sizeof...(args) << " arguments." << endl;
}

template<typename... Args>
void otherFunc(Args... args) {
  cout << "otherFunc called with " << sizeof...(args) << " arguments." << endl;
}

template<typename Func, typename... Args>
void callFunc(Func func, Args... args) {
  func(args...);
}

int main() {
  callFunc(&myFunc<double>, 1.0);
  callFunc(&otherFunc<double, double, double>, 1.0, 2.0, 3.0);
  return 0;
}

我不确定我是否会推荐这个解决方案,但它应该有效。

运行上面代码的输出:

myFunc called with 1 arguments.
otherFunc called with 3 arguments.

你也许还应该看看:参数数量未知的 C++ 模板函数如果你是模板函数的新手。


0
投票

您可以使用

std::variant
将函数作为单个参数传递。

#include <iostream>
#include <optional>
#include <variant>

using std::cout;
using std::get;
using std::optional;
using std::variant;

namespace {

void first_function(double z) {
    cout << "first_function z:" << z << "\n";
}

void second_function(double x, double y, double z) {
    cout << "first_function x:" << x << " y:" << y << " z:" << z << "\n";
}

using Fn1_t = void(*)(double);
using Fn3_t = void(*)(double,double,double);
using Fn_t = variant<Fn1_t, Fn3_t>;

void compute(Fn_t fn, optional<double> x, optional<double> y, double z) {
    if (x.has_value() && y.has_value()) {
        get<1>(fn)(x.value(), y.value(), z);
    } else {
        get<0>(fn)(z);
    }
}

} // anon

int main() {
    compute(&first_function, {}, {}, 10.0);
    compute(&second_function, 8.2, 9.1, 10.0);
}
© www.soinside.com 2019 - 2024. All rights reserved.