Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variadic template constructor with multiple parameters packs

I have read this, this, this and many others... but none of these posts answers or is applicable to my specific problem.

I have a struct X with a variadic template constructor:

struct X
{
    template<typename... T>
    X(T... t)   { /*...*/ }
};

And I have a structure Y that contains two objects of type X. I would like to define a template constructor for Y, allowing to properly initialize both members of type X with distinct parameters list, ie something that looks like the following code (which obviously does not work):

struct Y
{
    template<typename... U, typename... V>
    Y(U&&... u, V&&... v)                                // this does not work
        : x1(std::forward(u)...), x2(std::forward(v)...) // this is was I need to do
        {}

    X x1, x2;
};

How could I do that, using wrappers, tuples or any suitable metaprogramming machinery ? A C++14 solution is acceptable.

like image 449
shrike Avatar asked Jul 02 '26 19:07

shrike


1 Answers

Bog-standard index_sequence trick.

struct Y
{
private:
    template<typename... U, typename... V,
             std::size_t... UIs, std::size_t... VIs>
    Y(std::tuple<U...>&& u, std::tuple<V...>&& v,
      std::index_sequence<UIs...>, std::index_sequence<VIs...>)
        : x1(std::get<UIs>(std::move(u))...), 
          x1(std::get<VIs>(std::move(v))...)  
        {}
public:
    template<typename... U, typename... V>
    Y(std::tuple<U...> u, std::tuple<V...> v)
        : Y(std::move(u), std::move(v),
            std::index_sequence_for<U...>{},
            std::index_sequence_for<V...>{})
        {}

    X x1, x2;
};

In C++17, just use make_from_tuple:

struct Y
{
public:
    template<typename... U, typename... V>
    Y(std::tuple<U...> u, std::tuple<V...> v)
        : x1(std::make_from_tuple<X>(std::move(u))),
          x2(std::make_from_tuple<X>(std::move(v)))
        {}

    X x1, x2;
};
like image 76
T.C. Avatar answered Jul 04 '26 07:07

T.C.