Always associate a mutex with its controlled data

Consider the following sketch of a thread-safe StreamingAverage class. There is a bug here; can you find it?

    class StreamingAverage {      double m_sum = 0;      int m_count = 0;      double m_last_average = 0;      std::mutex m_mtx;    public:      // Called from the single producer thread      void add_value(double x) {        std::lock_guard lk(m_mtx);        m_sum += x;        m_count += 1; // A      }      // Called from the single consumer thread      double get_current_average() {        std::lock_guard lk(m_mtx);        m_last_average = m_sum / m_count; // B        return m_last_average;      }      // Called from the single consumer thread      double get_last_average() const {        return m_last_average; // C      }      // Called from the single consumer thread double get_current_count() const { ...

Get Mastering the C++17 STL now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.