Bind member function to instance with variadic arguments
Go to solution
Solved by Unimportant,
10 hours ago, Pinguinsan said:<snip>
The problem is that a lambda cannot be converted to a function pointer if it has a capture.
A solution would be to wrap the callbacks in std::function. However, std::function's cannot be stored in a std::unordered_set as unordered_set relies on std::hash and std::equal_to, both of which don't operate on std::function.
Small example using std::vector instead:
#include <functional> #include <vector> #include <iostream> template <class... Params> class Event { public: template <class T> using MemberPtr = void (T::*)(Params...); using Callback = std::function<void(Params...)>; template <class T> void Subscribe(T* t, MemberPtr<T> m) { const auto lambda = [=](Params&&... params) { (t->*m)(std::forward<Params>(params)...); }; Addcallback(lambda); } void Notify(Params&&... params) const { for (const auto& callback : mCallbacks) { callback(std::forward<Params>(params)...); } } private: void Addcallback(Callback callback) { mCallbacks.emplace_back(callback); } std::vector<Callback> mCallbacks; }; struct EventListener { void eventListenerCallback(int i) { std::cout << "Received " << i << std::endl; } }; struct DoublingListener { void eventListenerCallback(int i) { std::cout << "Double of received value " << i * 2 << std::endl; } }; int main() { Event<int> event; EventListener listener; DoublingListener doublingListener; event.Subscribe(&listener, &EventListener::eventListenerCallback); event.Subscribe(&doublingListener, &DoublingListener::eventListenerCallback); event.Notify(1337); return 0; }
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now