包扩展的多重继承
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。
我最近在生产代码中看到了这个,但不太明白它的作用:
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。