C++11 Variadic Class 处理程序管理器

C++11 Variadic Class Handler Manager

我正在尝试创建一个模板 class(事件 class 管理器),它将实例化多个事件 class 对象。我能够让它为一个 class 工作,但无法让它在可变情况下工作。我正在尝试让 class_mgr class 接收事件列表 classes。对于每一个,我都希望在 std::array.

中有一个条目
#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;
};

如果我明白你的意思,那就很简单了。
只需将 class 模板声明变为:

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_)), ...);
}