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

时间:2018-05-19 20:38:14

标签: c++ c++11 templates variadic

我试图创建一个模板类(事件类管理器)来实例化多个事件类对象。我能够让它适用于一个类,但是无法在可变参数的情况下使它工作。我试图让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;
};

1 个答案:

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