I currently have a system to "connect" signal
s to functions. This signal
is a variadic template that has as template parameters the arguments of the functions if can connect
to.
In the current implementation, I obviously cannot connect to functions whose arguments aren't exactly the same (or those that can be converted to) as the signal
's parameters. Now, as I'm trying to mimic Qt's signal
/slot
/connect
, I'd also like to connect a signal
of N
parameters to a slot
of M<N
parameters, which is perfectly well-defined (i.e. ignore the >M
parameters of the signal and just pass the first M to the connected function). For an example of the code I have in its most simplistic form, see Coliru.
So the question is two-fold:
- How do I make the
connect
call work for a functionvoid g(int);
? - How do I make the
emit
call work for a functionvoid g(int);
?
I'm guessing I'll have to make some "magic" parameter pack reducer for both the slot
and the , but I can't see how it all should fit together so it's quite hard to actually start trying to code a solution. I'm OK with a C++17-only solution, if at least Clang/GCC and Visual Studio 2017 can compile it.
The code linked above for completeness:
#include <memory>
#include <vector>
template<typename... ArgTypes>
struct slot
{
virtual ~slot() = default;
virtual void call(ArgTypes...) const = 0;
};
template<typename Callable, typename... ArgTypes>
struct callable_slot : slot<ArgTypes...>
{
callable_slot(Callable callable) : callable(callable) {}
void call(ArgTypes... args) const override { callable(args...); }
Callable callable;
};
template<typename... ArgTypes>
struct signal
{
template<typename Callable>
void connect(Callable callable)
{
slots.emplace_back(std::make_unique<callable_slot<Callable, ArgTypes...>>(callable));
}
void emit(ArgTypes... args)
{
for(const auto& slot : slots)
{
slot->call(args...);
}
}
std::vector<std::unique_ptr<slot<ArgTypes...>>> slots;
};
void f(int, char) {}
int main()
{
signal<int, char> s;
s.connect(&f);
s.emit(42, 'c');
}
Aucun commentaire:
Enregistrer un commentaire