Search code examples
c++variadic-templatesparameter-pack

Applying a function to a parameter pack


I'm playing around with parameter packs, and I'm trying to apply a mapping via a lambda function which adds 1 to each member of the parameter pack as shown. However, I get the output 4 while 234 is expected.

#include <iostream>

// method to print a variadic list of arguments
template<typename... Args>
void print(const Args &... args) {
    (std::cout << ... << args) << std::endl;
}

// transform each element of argument list 
// and then perfect forward the result 
template<typename F, typename... Args>
auto mapping(F f, Args &&... args) {
    return (f(std::forward<Args>(args)), ...);
}

int main() {
    print(1,2,3); // 123 (OK)
    print(mapping([](auto &&a) {return a + 1;}, 1, 2, 3)); // 4 (!) (234 expected)
}

How do I pass the mapped parameter pack 1,2,3 --> 2,3,4 to the variadic function print above?


Solution

  • You can't return a parameter pack. The closest thing is std::tuple.

    Something like this:

    template<typename F, typename ...Args>
    auto mapping(F f, Args &&... args)
    {
        // Note `{...}` instead of `(...)`, forcing the call order of `f`.
        return std::tuple{f(std::forward<Args>(args))...};
    }
    

    You'll need to modify your printing function to accept tuples too.