Если у ваших клиентов есть weak_ptr
, и ваша логика может блокировать его или нет, и действует независимо, тогда передайте weak_ptr
.
В качестве конкретного тривиального примера:
mutable std::mutex m_mutex;
mutable std::vector<std::weak_ptr<std::function<void(int)>>> m_callbacks;
void clean_callbacks(int x) {
auto l = std::unique_lock<std::mutex>(m_mutex);
auto it = std::remove_if( begin(m_callbacks), end(m_callbacks), [](auto w){ return !w.lock(); } );
m_callbacks.erase( it, end(m_callbacks) );
}
void call_callbacks() {
clean_callbacks();
auto tmp = [&]{
auto l = std::unique_lock<std::mutex>(m_mutex);
return m_callbacks;
}();
for (auto&& wf:tmp) {
if(auto sf = wf.lock()) {
(*sf)(x);
}
}
}
clean_callbacks
имеет лямбду, которая принимает weak_ptr
.Он используется для удаления любых m_callbacks
, чье время жизни истекло.
Этот код используется в простом вещателе, где широковещательные передачи происходят намного чаще, чем недействительные прослушиватели, поэтому ожидание следующей трансляции устраняет мертвого прослушивателяхорошая стратегия.