Как да разширя пакета с параметри от базови класове и да извикам членска функция на всеки един?

Опитвам се да използвам различни шаблони за съставяне на клас. Идеята е, че класът Composer просто агрегира определен брой променливи и препраща извиквания на функции към всички инстанцирани променливи.

Първо използвам следния прост клас обвивка:

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

    WrapperType() : wrapee_{}
    {}
};

Това се използва със следния клас Composer, който се надяваме да произлиза от WrapperType, създаден за всеки тип в пакета с параметри Args:

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

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

Ако приемем, че всеки опакован тип има display() членска функция, как мога да извикам функцията display() за всеки тип в пакета с параметри?

Т.Е. Ако имам:

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

Бих искал myComposer.display() да се обади на display() за T1, T2, T3.


person mark    schedule 29.09.2014    source източник
comment
възможен дубликат на защо разширяването на пакета с параметри е толкова ограничено?   -  person Pradhan    schedule 29.09.2014


Отговори (1)


Има само няколко контекста, в които може да възникне пакет-разширяване ([temp.variadic] / p5).

В c++11 и c++14 не можете да създадете pack-expansion от извикване на функция, но можете да го разширите, т.е. в рамките на масив initializer-list:

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

ДЕМО

В c++17 може да се използват сгъваеми изрази:

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

ДЕМО 2

person Piotr Skotnicki    schedule 29.09.2014
comment
Благодаря, изглежда доста елегантно. Мислех да конвертирам пакета с параметри в boost::mpl::vector и да използвам boost::mpl::for_each - но мисля, че това е по-чисто. - person mark; 29.09.2014