Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am trying to use variadic templates for class composition. The idea is that the Composer class simply aggregates a number of variables and forwards function calls to all instantiated variables.

Firstly I am using the following simple wrapper class:

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

    WrapperType() : wrapee_{}
    {}
};

This is used with the following Composer class, which hopefully derives from WrapperType instantiated for each type in the parameter pack Args:

template< typename... Args >
struct Composer : public WrapperType<Args>...
{
    Composer() : WrapperType<Args>{}...
    {}

    void display()
    {
        ((WrapperType<Args>...)::wrapee_).display();   // HOW?
    }
};

Assuming every wrapped type has a display() member function, how can I call the display() function for every type in the parameter pack?

I.E. If I have:

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

I would like myComposer.display() to call display() for T1, T2, T3.

like image 942
mark Avatar asked Feb 12 '23 22:02

mark


1 Answers

There are only few contexts where pack-expansion can occur ([temp.variadic] / p5).

In c++11 and c++14 you can't create pack-expansion from a function call, but you can expand it i.e. within an array initializer-list:

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

DEMO

In c++17 one can use fold-expressions:

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

DEMO 2

like image 65
Piotr Skotnicki Avatar answered Feb 14 '23 17:02

Piotr Skotnicki