Home > Mobile >  Multiple inheritance from a pack expansion
Multiple inheritance from a pack expansion

Time:03-27

I recently saw this in production code and couldn't quite figure out what it does:

template <class... Ts>
struct pool : pool_type<Ts>... {
//...
};

I've never seen pack expansion happening for parent classes. Does it just inherit every type passed into the varargs?

The parents look like this:

template <class T>
struct pool_type : pool_type_impl<T> {
// ...
};

CodePudding user response:

Does it just inherit every type passed into the varargs?

Yes. It inherits publicly from each of the passed arguments. A simplified version is given below.

From Parameter pack's documentation:

Depending on where the expansion takes place, the resulting comma-separated list is a different kind of list: function parameter list, member initializer list, attribute list, etc. The following is the list of all allowed contexts:

  • Base specifiers and member initializer lists:
    A pack expansion may designate the list of base classes in a class declaration.

Example

struct Person 
{
    Person() = default;
    Person(const Person&)
    {
        std::cout<<"copy constrcutor person called"<<std::endl;
    }
};
struct Name 
{
    Name() = default;
    Name(const Name&)
    {
        std::cout<<"copy constructor Name called"<<std::endl;
    }
};

template<class... Mixins>
//---------------vvvvvvvvv---------->used as list of base classes from which X inherits publicly
class X : public Mixins...
{
public:
//-------------------------------vvvvvvvvvvvvvvvvv---->used as member initializer list
    X(const Mixins&... mixins) : Mixins(mixins)... {}
};
int main()
{
    Person p;
    Name n;
    X<Person, Name> x(p, n); //or even just X x(p, n);  works with C  17 due to CTAD
    return 0;
}

The output of the above program can be seen here:

copy constrcutor person called
copy constructor Name called
constructor called

Explanation

In the above code, the X class template uses a pack expansion to take each of the supplied mixins and expand it into a public base class. In other words, we get a list of base classes from which X inherits publicly. Moreover, we also have a X constructor that copy-initializes each of the mixins from supplied constructor arguments.

  • Related