Инициализировать более одного неизвестного базового класса

Если базовый класс неизвестен библиотеке (он известен клиенту), обработать его конструктор не так уж и сложно. Код выглядит так:

template<typename Parent>
struct AAAAA : public Parent
{
    using Parent::Parent;

    template<typename ...Args>
    AAAAA(int a, int b, Args ...args) : Parent(args...) {}
};

Каков наилучший подход, если все>1 базовые классы неизвестны?

template<typename P1, typename P2>
struct AAAAA : public P1, public P2
{
    // ...CTOR....???
};

Мои первые мысли таковы:

  • Пакет параметров "разделенного" типа.
  • 2 кортежа, преобразованных в пакеты параметров.

Что касается обеих мыслей, на этот раз я не знаю, как и возможно ли это.

2 ответа

Решение

Здесь пригодится std::make_from_tuple.

Вот как вы можете использовать кортеж для одного родителя:

#include <tuple>
struct foo { 
    foo(int,double){}
    foo(const foo&) = delete;
    foo(foo&&) = default;     
};

template<typename Parent>
struct A : public Parent
{
    template<typename T>
    A(const T& args) : Parent(std::make_from_tuple<Parent>(args)) {}
};

int main() {
    A<foo> a{std::make_tuple(1,2.0)};
}

Добавление второго родителя должно быть простым.

Обратите внимание, что Parent должен быть, по крайней мере, подвижным, чтобы эта работа работала.

Вы можете потребовать от клиентов предоставить уже построенные объекты. Его легко понять и не нужно много печатать. Это требует, чтобы они были подвижными.

#include <iostream>
#include <utility>

struct foo { 
    foo(int x, double y) { std::cout << x << ' ' << y << '\n'; }
};

struct bar { 
    bar(const std::string& x) { std::cout << x << '\n'; }
};

template<typename P1, typename P2>
struct A : public P1, public P2 {
    A(P1&& p1, P2&& p2) : P1(std::move(p1)), P2(std::move(p2)) {}
};

int main() {
    A<foo, bar> afb({1, 2.3}, {"hello"});
}
Другие вопросы по тегам