Search code examples
c++templatesc++17variadic-templatesvariadic-functions

Invoke function with each argument


I'd like to invoke a function with each argument passed as a parameter pack. I have already written a simple template function:

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

It works fine when I use it with a function taking only one parameter:

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

But when I try to call a function taking two and more arguments:

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

it gives an error too few arguments for call. How could I fix it? A solution may be created in C++17.


Solution

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

    Here the caller bundles arguments into tuples, and we unpack them into the call. This makes the packaging of which arguments go where clear.

    We can move the apply call into the foreach function. In theory we csn detect if the target accepts 1 argument, and if not unpack the argument as a tuple, but I advise against it. To many things go wrong with muddled operations like that.

    apply_foreach(f, tuples...)
    

    is a clean and easy to specify function.