I am trying do to a basic signal/slot library with coroutines. The idea is that you have signal members, connect them with slots that have the same signature, and when you co_yield a signal it calls the registered slots.
Signal class looks like this:
template<typename... T>
class Signal {
public:
using slot_member = std::function<Slot(T...)>;
struct SignalArgs {
SignalArgs(std::span<slot_member> slots, T... args): args(args...), slots(slots) {}
std::tuple<T...> args;
std::span<slot_member> slots;
};
SignalArgs operator()(T... args) {
return SignalArgs(slots, args...);
}
private:
(...)
};
The important part is SignalArgs, since when you do a co_yield my_sig(…) it’s what the promise sees. the yield values is defined as such:
template<typename... T>
std::suspend_never yield_value(typename Signal<T...>::SignalArgs args)
{
for (auto f: args.slots) {
Slot s = std::apply(f(args.args));
s();
}
return {};
}
My problem is with the template deduction:
error: no matching member function for call to ‘yield_value’
co_yield s(3, “lil”);
^~~~~~~~
note: candidate function [with T = <>] not viable: no known conversion from ‘Signal<int, const char *>::SignalArgs’ to ‘typename Signal<>::SignalArgs’ for 1st argument
std::suspend_never yield_value(typename Signal<T…>::SignalArgs args)
Clearly the template deduction doesn’t work in this case and I wonder what can I do.