Home > Mobile >  how to deduce template multiple variadic parameters?
how to deduce template multiple variadic parameters?

Time:10-06

How to deduce template multiple variadic parameters and using as std::tuple as following code ? when compile, gets "'f': function does not take 5 arguments" error.

#include <tuple>

struct Type1 {
    int v = 0;
};

struct Type2 {
    int v = 0;
};

template <typename ..._t1, typename ..._t2>
void f(
    _t1...  t1,
    _t2...  t2) {
    // t1 as a, b, c
    // t2 as d, e

    auto    x = std::tuple<_t1...>(t1...);
    auto    y = std::tuple<_t2...>(t2...);
}

int main(int argc, char *argv[]) {
    Type1 a, b, c;
    Type2 d, e;

    // |-- _t1 --| |-- _t2 --|
    f(   a, b, c,     d, e); // 'f': function does not take 5 arguments

    return 0;
}

CodePudding user response:

It is not possible to unambiguously deduce _t1 and _t2 from the 5 parameters you pass to the function. The compiler cannot know if 0 or all 5 of the parameters belong to _t1 or _t2.

This is much simpler if the function has tuple arguments:

#include <tuple>

struct Type1 { int v = 0; };    
struct Type2 { int v = 0; };

template <typename... _t1, typename... _t2>
void f( std::tuple<_t1...>  t1, std::tuple<_t2...>  t2) {}

int main() {
    Type1 a, b, c;
    Type2 d, e;    
    f(std::make_tuple(a, b, c),std::make_tuple( d, e));   
}

This is also a way to go for the more general question:

how to deduce template multiple variadic parameters?

If you wrap them in a tuple (or other variadic template) you can get both packs deduced. If you don't like std::make_tuple you can follow the suggestion of Jarod42 and instead use

template <typename T1, typename T2> 
void f( std::initializer_list<t1>, std::initializer_list<t2>)

However, this assumes that there are only two different types involved. Perhaps thats what you wanted in the first place.

CodePudding user response:

There is a lambda trick to get a succinct syntax:

template<typename... T1>
auto f(T1...  t1) {
    return [=](auto... t2) {
        auto x = std::tuple(t1...);
        auto y = std::tuple(t2...);

        // ...
    };
}

Type1 a, b, c;
Type2 d, e;

f(a, b, c)(d, e);
  • Related