With the changes made in C++11 (such as the inclusion of std::bind), is there a recommended way to implement a simple single-threaded observer pattern without depen
Here's what I came up with.
This assumes no need to aggregate results from the listeners of a broadcast signal. Also, the "slot" or Signal::Listener is the owner of the callback. This ought to live with the object that your (I'm guessing...) lambda is probably capturing so that when that object goes out of scope, so does the callback, which prevents it from being called anymore.
You could use methods described in other answers as well to store the Listener owner objects in a way you can lookup.
template
class Signal
{
using fp = std::function;
std::forward_list > registeredListeners;
public:
using Listener = std::shared_ptr;
Listener add(const std::function &cb) {
// passing by address, until copy is made in the Listener as owner.
Listener result(std::make_shared(cb));
registeredListeners.push_front(result);
return result;
}
void raise(FuncArgs... args) {
registeredListeners.remove_if([&args...](std::weak_ptr e) -> bool {
if (auto f = e.lock()) {
(*f)(args...);
return false;
}
return true;
});
}
};
usage
Signal bloopChanged;
// ...
Signal::Listener bloopResponse = bloopChanged.add([](int i) { ... });
// or
decltype(bloopChanged)::Listener bloopResponse = ...
// let bloopResponse go out of scope.
// or re-assign it
// or reset the shared_ptr to disconnect it
bloopResponse.reset();
I have made a gist for this too, with a more in-depth example: https://gist.github.com/johnb003/dbc4a69af8ea8f4771666ce2e383047d