Chartas
Chartas

Reputation: 335

C++ Initialize inherited template base classes

I'm trying to pass arbitary parameters during construction to classes inherited through template parameter packs. Consider this example:

struct Zero {
    Zero() {}
};

struct Two {
    Two(int, int) {}
};

template <class... Pack>
struct User : Pack... {
    template <class... Params>
    User(Params... p) : Pack(p)... {} // How to do this correctly?
};

auto test = User<Zero, Two>(1,2);

If I now try to construct an object of type User<Zero, Two> how can I pass the Params to the correct constructor?

The most obvious workaround would be to have a tuple constructor taking exactly one tuple for each type User could accept, but this requires me to modify Zero and Two, which is very difficult in my use case.

Is this possible? Ohter possible workarounds are welcome as well.

Upvotes: 1

Views: 144

Answers (1)

Brian Bi
Brian Bi

Reputation: 119069

You need to have the User constructor accept a sequence of tuples, and then forward the arguments from each individual tuple to the corresponding base class.

template <class... Tuples>
User(Tuples&&... t) : Pack(std::make_from_tuple<Pack>(std::forward<Tuples>(t)))... {}

Note that due to guaranteed copy elision, temporaries of type Pack... will not be instantiated.

Live on Coliru

Upvotes: 6

Related Questions