来自包扩展的多重继承

发布于 2025-01-17 05:16:02 字数 298 浏览 1 评论 0原文

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

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

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

父母的表情是这样的:

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

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> {
// ...
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

玩物 2025-01-24 05:16:02

它只是继承传递给可变参数的每种类型吗?

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

来自参数包的文档

根据扩展发生的位置,生成的逗号分隔列表是不同类型的列表:函数参数列表、成员初始值设定项列表、属性列表等。以下是所有允许的上下文的列表:

  • 基本说明符和成员初始值设定项列表
    包扩展可以在类声明中指定基类列表

示例

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

上述程序的输出可以在此处查看:

copy constrcutor person called
copy constructor Name called
constructor called

解释

在上面的代码中,X< /code> 类模板使用包扩展来获取每个提供的 mixin 并将其扩展为公共基类。换句话说,我们得到了 X 公开继承的基类列表。此外,我们还有一个 X 构造函数,它从提供的构造函数参数中复制初始化每个 mixin。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文