# Function bind_weak ## Usage * Use `fastsignals::bind_weak` instead of `std::bind` to ensure that nothing happens if method called when binded object already destroyed * Pass pointer to T class method as first argument, `shared_ptr` or `weak_ptr` as second argument * Example: `bind_weak(&Document::save(), document, std::placeholders::_1)`, where `document` is a `weak_ptr` or `shared_ptr` ## Weak this idiom The `fastsignals::bind_weak(...)` function implements "weak this" idiom. This idiom helps to avoid dangling pointers and memory access wiolations in asynchronous and/or multithreaded programs. In the following example, we use weak this idiom to avoid using dangling pointer wehn calling `print()` method of the `Enityt`: ```cpp struct Entity : std::enable_shared_from_this { int value = 42; void print() { std::cout << "print called, num = " << value << std::endl; } std::function print_later() { // ! weak this idiom here ! auto weak_this = weak_from_this(); return [weak_this] { if (auto shared_this = weak_this.lock()) { shared_this->print(); } }; } }; int main() { auto entity = std::make_shared(); auto print = entity->print_later(); // Prints OK. print(); // Prints nothing - last shared_ptr to the Entity destroyed, so `weak_this.lock()` will return nullptr. entity = nullptr; print(); } ``` ## Using bind_weak to avoid signal receiver lifetime issues In the following example, `Entity::print()` method connected to the signal. Signal emmited once before and once after the `Entity` instance destroyed. However, no memory access violation happens: once `Entity` destoryed, no slot will be called because `bind_weak` doesn't call binded method if it cannot lock `std::weak_ptr` to binded object. The second `event()` expression just does nothing. ```cpp #include #include #include using VoidSignal = fastsignals::signal; using VoidSlot = VoidSignal::slot_type; struct Entity : std::enable_shared_from_this { int value = 42; VoidSlot get_print_slot() { // Here fastsignals::bind_weak() used instead of std::bind. return fastsignals::bind_weak(&Entity::print, weak_from_this()); } void print() { std::cout << "print called, num = " << value << std::endl; } }; int main() { VoidSignal event; auto entity = std::make_shared(); event.connect(entity->get_print_slot()); // Here slot called - it prints `slot called, num = 42` event(); entity = nullptr; // Here nothing happens - no exception, no slot call. event(); } ```