A simple thread-safe Deque in C++
It's probably worth accepting a second template argument for an Allocator to be passed through to the std::deque:

template&lt;class T, class Allocator = std::allocator&lt;T&gt;&gt;
class ThreadSafeDeque {
    std::deque&lt;T, Allocator&gt; deque;
};


Technically, we do need to include &lt;condition_variable&gt;; we're not allowed to assume that &lt;mutex&gt; always pulls it in.

I don't like the interface to pop_front_waiting() - why does the caller have to pass an lvalue reference, instead of simply being returned the value?  Return-value optimisation will ensure there's no unnecessary copy.

The locking logic all looks good to me.  We can avoid the lock.unlock() by using a simple lock-guard with smaller scope:

void push_back(const T &amp;t)
{
    {
        std::lock_guard&lt;std::mutex&gt; lock{ mutex }; 
        deque.push_back(t);
    }
    condition.notify_one(); // wakes up pop_front_waiting  
}


From C++17, we can use constructor deduction and omit the template parameter from std::lock_guard and std::unique_lock, making the code a little easier to read.

It's helpful to show that members are intentionally default-constructed, and it pacifies g++ -Weffc++:

std::deque&lt;T&gt; deque = {};
std::mutex mutex = {};
std::condition_variable condition = {};