Перегрузка унаследованных конструкторов

Дан следующий базовый класс:

class Base {
    int a, b;
public:
    Base(int a, int b=42): a(a), b(b) { }
};

И класс, который является производным от базы:

class Derived: public Base {
    using Base::Base; // inherit Base constructors
    bool c;
public:
    Derived(int a): Base(a), c(true) { }
    Derived(int a, int b): Base(a, b), c(true) { }
};

Есть ли способ избежать создания двух отдельных конструкторов для Derived и вместо этого перегрузить унаследованный Base конструкторы для инициализации дополнительного члена Derived?

Я думал использовать что-то вроде этого:

template <typename... Args, 
    typename std::enable_if_t<std::is_constructible_v<Base, Args&&...>, int> = 0>
explicit Derived(Args&&... args):
    Base(std::forward<Args>(args)...), c(true) {}

Это близко, но слишком многословно и не работает, если конструкторы базового класса наследуются. т.е. если using Base::Base присутствует в классе (то есть по умолчанию эти конструкторы и не инициализирует поле b).

Это работает, однако, если унаследованные конструкторы базового класса отсутствуют, т.е. using Base::Base,


Это единственный способ получить эту работу? т.е. удалив using Base::Base и используя конструктор шаблона variadic в каждом производном классе? Есть ли менее подробный способ перегрузки унаследованных конструкторов?

Я использую C++17.

2 ответа

Решение

В этом случае все, что вам нужно сделать, это предоставить c с инициализатором в классе

class Derived : public Base {
    using Base::Base;
    bool c = true;
};

позволяет использовать BaseКонструкторы и инициализируют c в true во всех случаях.

Кажется, что вы ищете способ наследовать Baseконструкторы при инициализации членов Derived к чему-то конкретному. Для этого мы можем по умолчанию инициализировать член:

class Derived: public Base {
public:
    using Base::Base;
private:
    bool c = true;
};

Построение Derived(42) вызовет Base(int) конструктор, но также инициализировать c в true,

Другие вопросы по тегам