包扩展的多重继承

Multiple inheritance from a pack expansion

我最近在生产代码中看到了这个,但不太明白它的作用:

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

我从未见过 parent 类 的包扩展。它只是继承传递给可变参数的每种类型吗?

parent 看起来像这样:

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

Does it just inherit every type passed into the varargs?

是的。它从每个传递的参数继承 publicly 。下面给出一个简化版本。

来自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.

例子

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

上面程序的输出可见here:

copy constrcutor person called
copy constructor Name called
constructor called

说明

在上面的代码中,X class 模板使用 pack 扩展 获取每个提供的 mixin 和 expand它变成了 public 基础 class。换句话说,我们得到一个基 classes 的列表,X 从中继承 publicly。此外,我们还有一个 X 构造函数,它 copy-initializes 来自提供的构造函数参数的每个 mixin。