template class threadsafe_queue { private: std::unique_ptr try_pop_head() { std::lock_guard head_lock(head_mutex); if(head.get()==get_tail()) { return std::unique_ptr(); } return pop_head(); } std::unique_ptr try_pop_head(T& value) { std::lock_guard head_lock(head_mutex); if(head.get()==get_tail()) { return std::unique_ptr(); } value=std::move(*head->data); return pop_head(); } public: std::shared_ptr try_pop() { std::unique_ptr const old_head=try_pop_head(); return old_head?old_head->data:std::shared_ptr(); } bool try_pop(T& value) { std::unique_ptr const old_head=try_pop_head(value); return old_head; } void empty() { std::lock_guard head_lock(head_mutex); return (head==get_tail()); } };