Please consider the following code for a type that can compose different mixin types. The constructor of the composition type takes a variadic list of tuples that represent the arguments for the constructors of the composed types:
#include <string>
#include <tuple>
#include <utility>
struct MixinBase {
MixinBase() = default;
// Note; want to delete these instead of default them.
MixinBase(const MixinBase&) = default;
MixinBase(MixinBase&&) = default;
};
struct MixinA : public MixinBase {
MixinA(int, const std::string&, const std::string&) {}
};
struct MixinB : public MixinBase {
MixinB(const std::string&, const std::string&) {}
};
template <typename... Mixins>
struct Composition : private Mixins... {
template <typename... Packs>
Composition(Packs&&... packs)
: Mixins(constructMixin<Mixins>(
std::forward<Packs>(packs),
std::make_index_sequence<std::tuple_size_v<Packs>>{}))...
{
}
private:
template <typename Mixin, typename Pack, size_t... Indexes>
Mixin constructMixin(Pack&& arguments, std::index_sequence<Indexes...>) const
{
return Mixin(std::get<Indexes>(std::forward<Pack>(arguments))...);
}
};
int main()
{
std::string a{"a"};
std::string b{"b"};
Composition<MixinA, MixinB>(
std::forward_as_tuple(7, a, b), std::forward_as_tuple(a, b));
return 0;
}
This works perfectly fine, however, I would like to avoid the indirection through constructMixin, and directly construct every inherited mixin object so that the need for a copy/move constructor on the mixin type can be avoided. Is this possible?