我试图创建一个模板类(事件类管理器)来实例化多个事件类对象。我能够让它适用于一个类,但是无法在可变参数的情况下使它工作。我试图让class_mgr类接受事件类列表。对于每一个,我想在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;
};
答案 0 :(得分:0)
如果我明白你的意思,那就很简单了 只需将类模板声明转换为:
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_)), ...);
}