No. The caller needs to acquire a lock since it gets a reference to the data instead of a copy. You can't somehow make reference to an int
thread-safe for all code that uses it.
If you need a thread-safe operation on the data and don't want the caller to be responsible, you have two options: a) add that operation in the API of your class, or b) implement a wrapper type around the int
reference.
A wrapper can be complicated to implement correctly, as you now need to worry about every possible corner case. Is it copyable? Movable? Both in a thread-safe manner?
So I'd opt for adding the operation as an API. Like:
class BlockingVector{
// ...
void setVal(size_t index, int newVal)
{
std::lock_guard<std::mutex> lock(m_mutex);
m_vector[index] = newVal;
}
// Change: return copy, not reference.
int operator [](size_t p_index) const {
std::lock_guard<std::mutex> lock(m_mutex);
return m_vector[p_index];
}
};
However, this can be a confusing API. So I'd suggest not overloading operator[]
instead use a normal function:
int getVal(size_t p_index) const {
std::lock_guard<std::mutex> lock(m_mutex);
return m_vector[p_index];
}
Note that to be able to lock the mutex in a const
function, you need to make it mutable:
class BlockingVector{
// ...
mutable std::mutex m_mutex;
You should read this for more information on mutexes and const
functions:
Should mutexes be mutable?