2

I am considering to use multiple inheritance as a part of the design of my library. The user defines components that are described as a stateless class (Component1, Component2, Component3) each with the same typedefs and static members. See the example of Component1 below. Other component classes are defined the same way, defining the sub classes, typedefs and static members with the same names.

I also want the user to be able to define the combination of several components as another class (Combined). One way of doing it is through the multiple inheritance (see definition below), but I would need the combined class to be automatically aware of the components it was build from. The order of the components matters.

struct Component1{
    using MyType = int; //each class defines several standard typedefs
    using return_type = int; 
    struct Parameters {
        constexpr auto static parameter_set = 42;
    }; //classes also define static subclasses
    static return_type myfun(MyType); //and static functions that get defined elsewhere.
};

struct Component2 {/* This class have the same duck-type (public interface) as Base1*/  };

struct Component3 {}; //likewise

struct Combined: public Component1, public Component3, public Component2 {
   //I want this to be automatically generated:
   using members = std::tuple<Component1, Component3, Component2>; 
};

Or perhaps there is another way of delivering a similar API?

Quentin
  • 62,093
  • 7
  • 131
  • 191
Adam Ryczkowski
  • 7,592
  • 13
  • 42
  • 68

2 Answers2

2

You cannot retrieve the list of base classes from a C++ class (yet?).

However, you could provide a Combine class template of the following form:

template <class... Components>
struct Combine {
    using members = std::tuple<Components...>;

    // ...
};

Which you can then use in the following ways:

using Combined = Combine<Component1, Component3, Component2>;
// or
struct Combined : Combine<Component1, Component3, Component2> {
    // ...
};
Quentin
  • 62,093
  • 7
  • 131
  • 191
1

One way:

template <class... Components>
struct Combine : Components... {
    using members = std::tuple<Components...>;

    template<class... Args>
    Combine(Args&&... args)
        : Components(args...)...
    {}
};

struct A { A(int); };
struct B { B(int); };

struct C : Combine<A, B> {
    using Combine::Combine;
};

int main() {
    C c(1);
}
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271