C++11 可变类处理程序管理器

标签 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;
};

最佳答案

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

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

关于C++11 可变类处理程序管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50429283/

相关文章:

c++ - std::unique_ptr 编译器错误:派生类的成员无法访问基类的私有(private)成员

c++ - nullptr 是假的吗?

c++11 - STL map::insert 是否应该支持 move_iterators 的 move 语义?

C++ 模板函数问题与创建

ruby - 什么模板系统使用 <?r ... ?>

c++ - 将非空终止 c 字符串转换为终止 c 字符串的最干净方法

c++ - <image>.h - 这个 -e 来自哪里?

c++ - 在其他类中使用抽象类的构造函数

python - 如何在 Django 中使用模板调用模型上的自定义方法?

c++ - unordered_map 中两种插入方式的区别