Magix
Magix

Reputation: 5349

C++ template type circularity and non-template pointer to template instance

For reference, here is the minimal example : http://coliru.stacked-crooked.com/a/75354688a0a6af64

In this example, I have a single problem of template type circularity that, in my view, could be solved in two ways :

What is the best way to make this work in a cleanly ?

EDIT : link updated

Upvotes: 1

Views: 110

Answers (2)

Jarod42
Jarod42

Reputation: 217740

You cannot fully type erase functor which accept template argument.

But if you know the subset of template argument to handle, std::any/ std::variant might help:

In your case non-supported event do no-op, so "your" controller:

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}{}
};

becomes

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);
        };
    }
};

Demo

Upvotes: 1

darune
darune

Reputation: 10982

The issue seems to be not what you think it is.

std::vector<std::any> modules;
//...
    for(auto mod : modules) { mod.dispatch(Event{event, this}); } // should probably use an algorithm here

First you cannot iterate a tuple like that. Secondly any doesn't have a dispatch method.

Upvotes: 0

Related Questions