简体   繁体   中英

c++ combine values from two (or more) parameter packs

How is it possible to combine values from two parameter packs in C++? In other words, how to write function

LetsStart<int, -1, 10, 3>("This is -1", "And this is 10", "3!!!");

which would output

-1 This is -1                                                                                                                                   
10 And this is 10                                                                                                                               
3 3!!! 

Ie it should pick 1st value from first pack and 1st value from second pack, then 2nd value from both packs, then 3rd value from both packs and so on...

In first my attempts I tried something like this

template<class T, T... Firsts, class TSecond>
void LetsStart(TSecond... Seconds) {
   Output((Firsts, Seconds)...);
}

but this did not work...

// Of course I wrote this function , but I believe there exists more correct and simple way to accomplish this task. So, could you point me out the way?

In C++11, you can use the following function:

template<typename T, T... V, typename F, typename... A>
void f(F &&f, A&&... args) {
    static_assert(sizeof...(V) == sizeof...(A), "Argument lists size mismatch");
    int arr[] = { 0, (std::forward<F>(f)(V, std::forward<A>(args)), 0)... };
    (void)arr;
}

It accepts two lists of parameters as requested and an extra function F , then it unpacks the parameters and pass the N-th of each list to the given function.
It should work also in case no parameters are provided.

In C++17 you can rewrite it as it follows:

template<typename T, T... V, typename F, typename... A>
void f(F &&f, A&&... args) {
    static_assert(sizeof...(V) == sizeof...(A));
    (std::forward<F>(f)(V, std::forward<A>(args)), ...);
}

In both cases I've checked that the two lists have the same size, for it wasn't specified what to do in such a case.

You can test the two functions with the example main below:

#include<utility>
#include<iostream>

// ...

int main() {
    auto l = [](auto v, auto s) { std::cout << v << " " << s << std::endl; };
    f<int, -1, 10, 3>(l, "This is -1", "And this is 10", "3!!!");
}

C++11 version:

CE: https://gcc.godbolt.org/z/xIUL1J

#include<iostream>

template<class... T>
void LetsStart(){}

template<class T, class U>
void print(T t, U u)
{
    std::cout << t << " " << u << '\n';
}

template<class T, T f,  T... ts, class A, class... Arg>
void LetsStart(A&& a, Arg&&... args){
    print(f, a);
    LetsStart<T, ts...>(args...);
}

void foo() {
    LetsStart<int, -1, 10, 3>("This is -1", "And this is 10", "3!!!");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM