A lightweight, header-only, and thread-safe Multicast Delegate implementation for C++17. This library allows multiple event handlers to be attached to a single delegate object and triggered simultaneously.
-
Multicast Support: Trigger multiple callbacks with a single call.
-
Thread-Safe: All operations (
add,remove,broadcast) are protected bystd::mutex. -
Smart Lifecycle Management:
-
Supports
add_weakto bindstd::shared_ptrobjects. -
Automatically detects and cleans up expired objects during broadcast to prevent dangling pointers.
-
Flexible Binding:
-
Lambdas: Support for stateful and stateless lambdas.
-
Static/Global Functions: Standard function pointer support.
-
Member Functions: Support for both Raw pointers (
add_raw) and Weak pointers (add_weak). -
Result Collection: If the delegate has a return type,
broadcast()returns astd::vectorcontaining results from all listeners. -
Exception Safety: Uses a "Snapshot" pattern during broadcast; callbacks are executed outside the main lock to prevent deadlocks, and exceptions in one listener won't stop others.
- Standard: C++17 or higher (uses
std::scoped_lock,if constexpr, andstd::is_invocable_v). - Threading: Requires a thread-compliant library (e.g.,
-pthreadon Linux).
| File | Description |
|---|---|
delegate.hpp |
The core template implementation. |
lambda_example.cpp |
Usage with Lambda expressions and Handles. |
functional_example.cpp |
Usage with global functions and return values. |
class_example.cpp |
Usage with class member functions and shared_ptr safety. |
Makefile |
Build script for all examples. |
Use the provided Makefile to compile all examples:
make#include "delegate.hpp"
// Declare a delegate that takes an int and returns void
Delegate<void(int)> OnScoreChanged;
// 1. Add a Lambda
auto handle = OnScoreChanged.add([](int score) {
std::cout << "Score is now: " << score << std::endl;
});
// 2. Broadcast
OnScoreChanged.broadcast(100);
// 3. Remove
OnScoreChanged.remove(handle);
auto player = std::make_shared<Player>();
// Will not crash even if 'player' is destroyed later
OnScoreChanged.add(player, &Player::OnScoreUpdate);
Handle add(Callable&&): Adds a lambda or functor. Returns a handle for later removal.Handle add(shared_ptr<T>, Method): Safely binds a member function.bool remove(Handle&): Removes a listener using its handle.void remove_all_for_object(void*): Removes all listeners associated with a specific object instance.std::vector<R> broadcast(Args...): Executes all valid listeners.add_weak(std::shared_ptr<T>, Method): Bind a weak pointer function.