Reputation: 5349
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 :
Controller
a template class and the Event
member pointer a non-template pointer to a template class instance (but how ?)std::any
or something like it to keep the Controller
class non-template (like is shown in the example, but doesn't compile)What is the best way to make this work in a cleanly ?
EDIT : link updated
Upvotes: 1
Views: 110
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);
};
}
};
Upvotes: 1
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