Как расширить пакет параметров базовых классов и вызвать функцию-член каждого из них?

Я пытаюсь использовать вариативные шаблоны для состава классов. Идея состоит в том, что класс 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)


Существует всего несколько контекстов, в которых может произойти pack-expansion ([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 можно использовать fold-expressions:

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