首页 > 解决方案 > C ++模板类型循环和指向模板实例的非模板指针

问题描述

作为参考,这里是最小的例子:http ://coliru.stacked-crooked.com/a/75354688a0a6af64

在这个例子中,我有一个模板类型循环的问题,在我看来,可以通过两种方式解决:

使这项工作干净利落的最佳方法是什么?

编辑:链接更新

标签: c++templateseventsvariadic-templatescircular-dependency

解决方案


您不能完全键入接受模板参数的擦除函子。

但是,如果您知道要处理的模板参数的子集,std::any/std::variant可能会有所帮助:

在您的情况下,不受支持的事件不执行任何操作,因此“您的”控制器:

template <typename ... Modules>
class Controller {
public:
    std::tuple<Modules...> modules;
        
    template<typename evt_t>
    void emit(evt_t event) { 
        std::apply([this](auto&&... args) {((args.dispatch(Event<evt_t>{event, this})), ...);}, modules);
    }
        
    Controller(std::tuple<Modules...> _modules) : modules{_modules}{}
};

变成

class Controller {
    std::function<void(std::any)> func;
public:
    template<typename evt_t>
    void emit(evt_t event) {
        func(event);
    }

    template <typename ... Modules, typename EventTags>
    Controller(std::tuple<Modules...> tmodules, EventTags event_tags)
    {
        func = [=, this](std::any any_ev){
            auto f = [&, this](auto tag){
                using EventType = typename decltype(tag)::type;
                if (auto* ev = std::any_cast<EventType>(&any_ev)) {
                    std::apply([=, this](auto&&... modules) {((modules.dispatch(Event<EventType>{*ev, this})), ...);}, tmodules);
                }
            };
            std::apply([&f](auto... tags){ (f(tags), ...); }, event_tags);
        };
    }
};

演示


推荐阅读