使用每个参数调用函数

Invoke function with each argument

我想调用一个函数,每个参数都作为参数包传递。 我已经写了一个简单的模板函数:

template<class Function, class... Args>
auto for_each_arg(Function f, Args&&... args) {
    (f(std::forward<Args>(args)), ...);
}

当我将它与仅接受一个参数的函数一起使用时,它工作正常:

void foo(int a) { }
for_each_arg(foo, 1);

但是当我尝试调用一个带有两个或更多参数的函数时:

void bar(int a, int b) { }
for_each_arg(bar, 1, 2);

它给出一个错误too few arguments for call。我该如何解决?可以在 C++17 中创建解决方案。

void bar(int a, int b) { }
for_each_arg(
  [](auto&&tup){
    return std::apply(bar, decltype(tup)(tup));
  }
)(std::make_tuple(1, 2));

这里调用者将参数打包成元组,我们将它们解包到调用中。这使得参数的包装很清楚。

我们可以将 apply 调用移到 foreach 函数中。理论上,我们 csn 检测目标是否接受 1 个参数,如果不接受,则将参数解压为元组,但我建议不要这样做。像这样乱七八糟的操作,很多事情都出问题了。

apply_foreach(f, tuples...)

是一个简洁且易于指定的函数。

古老的递归方式很简单

#include <iostream>

template <typename F>
void invoke_two_args (F)
 { }

template <typename F, typename A0, typename A1, typename ... Args>
void invoke_two_args (F f, A0 && a0, A1 && a1, Args && ... args)
 {
   f(std::forward<A0>(a0), std::forward<A1>(a1));

   invoke_two_args(f, std::forward<Args>(args)...);
 }

void bar(int a, int b)
 { std::cout << "bar: " << a << ' ' << b << '\n'; }

int main ()
 {
   // compile
   invoke_two_args(bar, 2, 3, 5, 7, 11, 13);

   // compilation error: wrong number of arguments
   // invoke_two_args(bar, 2, 3, 5, 7, 11, 13, 17);
 }

只有当参数列表不太长时,这是一个很好的解决方案。

你可以这样使用:

template <typename F, typename... Args>
auto curry(F&& f, Args&&... args) {
  if constexpr (std::is_invocable_v<F, Args...>) {
    return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
  } else {
    return [&](auto&&... more_args) {
      return curry(std::forward<F>(f), std::forward<Args>(args)..., more_args...);
    };
  }
}

int foo(int a, int b) { return a + b; }

// usage
auto func = curry(foo);
func(1)(2);