如何展开基类的参数包并调用每个基类的成员函数

How to expand parameter pack of base classes and call member function of each one?

本文关键字:基类 成员 调用 函数 何展开 参数      更新时间:2023-10-16

我正在尝试使用可变模板进行类组合。其思想是Composer类简单地聚合了许多变量,并将函数调用转发给所有实例化的变量。

首先,我使用以下简单的包装类:

template< typename T >
struct WrapperType
{
    typedef T wrapped_type;
    typedef typename wrapped_type::value_type value_type;
    wrapped_type wrapee_;
    WrapperType() : wrapee_{}
    {}
};

这与以下Composer类一起使用,该类有望从为参数包Args:中的每种类型实例化的WrapperType派生而来

template< typename... Args >
struct Composer : public WrapperType<Args>...
{
    Composer() : WrapperType<Args>{}...
    {}
    void display()
    {
        ((WrapperType<Args>...)::wrapee_).display();   // HOW?
    }
};

假设每个封装的类型都有一个display()成员函数,那么如何为参数包中的每个类型调用display()函数呢?

I.E.如果我有:

Composer< T1, T2, T3 > myComposer{};
myComposer.display();  

我希望myComposer.display()T1T2T3调用display()

只有少数上下文可以进行包扩展([temp.variadic]/p5)。

在c++11和c++14中,您不能从函数调用创建包扩展,但您可以扩展它,即在数组初始值设定项列表中:

void display()
{
    using discard = int[];
    (void)discard{ 0, ((void)WrapperType<Args>::wrapee_.display(), 1)... };
}  

演示

在c++17中,可以使用折叠表达式:

void display()
{
    (WrapperType<Args>::wrapee_.display(), ...);
}  

演示2