Менеджер обработчиков Variadic C ++ 11 - PullRequest
0 голосов
/ 19 мая 2018

Я пытаюсь создать шаблонный класс (менеджер класса событий), который будет создавать экземпляры нескольких объектов класса событий.Я могу заставить его работать для одного класса, но не могу заставить его работать в вариационном случае.Я пытаюсь получить класс class_mgr, чтобы взять в список классов событий.Для каждого я хотел бы получить запись в массиве std ::.

#include <array>

class handler {
public:
    void handle() {} 
};



enum event_class_types {
    eclass1 = 0,
    eclass2,
    num_classes,
};



class base {
};


template<typename handlerType>
class event_class1 : public base {
public:
    event_class1(handlerType& handler) : 
        handler_(handler) {}
private:
    handlerType& handler_;
};

template<typename handlerType>
class event_class2 : public base {
public:
    event_class2(handlerType& handler) : 
        handler_(handler) {}
private:
    handlerType& handler_;
};


namespace map {
    template<typename handlerType>
    struct event_class1 {
        using type = ::event_class1<handlerType>;
        static constexpr int id = eclass1;
    };

    template<typename handlerType>
    struct event_class2 {
        using type = ::event_class2<handlerType>;
        static constexpr int id = eclass2;
    };
}


//TODO: variadic
template<typename handlerType, template< typename T> class mapTypes>
class event_class_mgr 
{
public:
    event_class_mgr(handlerType& handler) : 
        handler_(handler)
    {
        add_class();
    }

private:
    void add_class( ) 
    {
        my_classes_[ mapTypes<handlerType>::id ] = new typename mapTypes<handlerType>::type(handler_);
    }


    handlerType handler_;
    std::array< base*, event_class_types::num_classes> my_classes_{};
};



int main(int argc, char** argv) {

    handler my_handler;

    event_class_mgr<handler, map::event_class1> cm(my_handler);
    //Trying to make this variadic, to pass multiple types to my handler
    //class_mgr<handler, map::event_class1, map::event_class2> cm(my_handler);
    //alternatively, i could just pass the enums?
    //class_mgr<handler, event_eclass1, event_eclass2> cm(my_handler);
    return 0;
};

1 Ответ

0 голосов
/ 20 мая 2018

Если я понял, что вы имеете в виду, это просто.
Просто включите объявление шаблона класса в:

template<typename handlerType, template< typename T> class... mapTypes>
class event_class_mgr {
    // ...
}

Затем обновите функцию-член add_class:

void add_class( ) 
{
    using accumulator_type = int[];
    accumulator_type accumulator = { (my_classes_[ mapTypes<handlerType>::id ] = new typename mapTypes<handlerType>::type(handler_), 0)... };
    (void)accumulator;
}

Использование C ++ 17 и, следовательно, выражений свёртывания уменьшило бы шаблон, но вы явно пометили вопрос как C ++ 11, так что ...

Просмотрите его и запустите на wandbox .


В качестве примечания, в C ++ 17 вы можете написать add_class как:

void add_class( ) 
{
    ((my_classes_[ mapTypes<handlerType>::id ] = new typename mapTypes<handlerType>::type(handler_)), ...);
}
...