Search code examples
c++inheritancec++17inherited-constructors

Overloading inherited constructors


Given the following base class:

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

And a class that is derived from base:

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) { }
};

Is there a way to avoid having to create two separate constructors for Derived and instead overload the inherited Base constructors to initialize the extra member of Derived?

I was thinking to use something like this:

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) {}

This is close, but is too verbose and does not work if the the base class's constructors are inherited. i.e. if using Base::Base is present in the class (then it defaults to those constructors and does not initialize the field b).

It works if the base class inherited constructors are not present i.e. removing using Base::Base.


Is this the only way to have this work? i.e. by removing using Base::Base and using a variadic template constructor in each derived class? Is there a less verbose way to overload the inherited constructors?

I am using C++17.


Solution

  • In this case all you need to do is provide c with an in class initializer

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

    allows you to use Base's constructors and will initialize c to true in all cases.