C++11 Blocking Queue learning exercise As part of my own C++11 learning exercise I have implemented this Blocking Queue using the new C++11 thread API. One of the aspects I would like to improve is efficiency i.e. in the take member function while returning the Job template type to be returned by reference instead of by value.

/*
 * blockingqueue.h
 *
 *  Created on: May 20, 2016
 *      Author: bravegag
 */

#ifndef BLOCKINGQUEUE_H_
#define BLOCKINGQUEUE_H_

#include &lt;condition_variable&gt;
#include &lt;mutex&gt;
#include &lt;thread&gt;
#include &lt;iostream&gt;
#include &lt;queue&gt;
#include &lt;chrono&gt;
#include &lt;cassert&gt;

using namespace std;

template&lt;class Job&gt;
class blocking_queue {
private:
    queue&lt;Job&gt; queue_;
    mutex mutex_;
    condition_variable not_empty_cond_;
    condition_variable not_full_cond_;
    int capacity_ = 0;

public:
    blocking_queue(int capacity) : capacity_(capacity) {
        // empty
    }

    void put(const Job&amp; job) {
        unique_lock&lt;mutex&gt; lock(mutex_);
        while (queue_.size() &gt;= capacity_) {
            cout &lt;&lt; "queue full, waiting for jobs to be taken" &lt;&lt; endl;
            not_full_cond_.wait(lock, [&amp;]() { return (queue_.size() &lt; capacity_); } );
        }
        queue_.push(job);
        not_empty_cond_.notify_one();
        assert(!queue_.empty());
    }

    Job take() {
        unique_lock&lt;mutex&gt; lock(mutex_);
        while (queue_.empty()) {
            cout &lt;&lt; "queue empty, waiting for jobs to be put" &lt;&lt; endl;
            not_empty_cond_.wait(lock, [&amp;]() { return !queue_.empty(); });
        }
        Job job = queue_.front();
        queue_.pop();
        not_full_cond_.notify_one();
        assert(queue_.size() &lt; capacity_);
        return job;
    }

    int size() const {
        return queue_.size();
    }

    virtual ~blocking_queue() {
        // empty
    }
};

#endif /* BLOCKINGQUEUE_H_ */
One of the aspects I would like to improve is efficiency i.e. in the take member function while returning the Job template type to be returned by reference instead of by value.


So what you would like is:

Job&amp; take()   ?


the problem is that you would return a reference to local variable which is Undefined Behaviour.

Just Job take() should be fine, compiler will use NRVO optimization so that no copy will be done, copy constructor call would be elided. You could return by moving: return std::move(job);, but that can prevent elision.

One place where you will have a copy constructor called is here:

Job job = queue_.front();


To prevent it you can implement move semantics into your Job class. Then replace above with:

Job job = std::move(queue_.front());


if you will not add any of the user defined constructor/destructor/assignment operator to your Job class, then compiler will add move constructor/assignment operator on  its own - depending whether it is possible.