20

In a subclass, I have a private std::mutex m field that I use in an implementation of a base class pure virtual method to return a value in a thread-safe way (the value can be updated by another thread):

int SubClass::get() const // implements 'virtual int get() = 0 const' of the base class
{            
    std::lock_guard<std::mutex> lck(m); 
    return value;
}

The compiler is telling me that this violates const correctness by producing an error:

error: binding 'const std::mutex' to reference of type 'std::lock_guard::mutex_type& {aka std::mutex&}' discards qualifiers

Is there a way to make this compliant and use std::lock_guard in a const-correct way? Simply changing it to const std::lock_guard changes nothing. I don't really understand which part is problematic, then again I'm quite new to C++ ...

w128
  • 4,680
  • 7
  • 42
  • 65

1 Answers1

40

The this pointer is implicitly const (it's actually an rvalue of type const SubClass *), so any member you are accessing are const implicitly.

If you could modify member object in a const function, then what would be the point of const? :)

The lock guard wants to modify the mutex, to lock and unlock it, but because it is const, it cannot, that is the problem. It doesn't matter if the lock guard is const or not, because that has nothing to do with the ability of the lock guard to modify the mutex or not.

To effectively solve this problem, there is a keyword you can use to mark member objects that can be modified in const qualified functions. Now obviously, you shouldn't abuse this feature and mark every object of your class with it:

class SubClass {
/*...*/
private:
    mutable std::mutex m;
  //^^^^^^^
/*...*/
}; 
Rakete1111
  • 47,013
  • 16
  • 123
  • 162
  • 4
    Just to nit-pick (hey, this is C++), `this` is not a const pointer. That is, the type is still `const SubClass*` - it's just its value is an rvalue, so you cannot assign to it. It's as if the compiler supplied a magic macro `#define this (this_ + 0)`, and the function's hidden argument was named `this_`. http://coliru.stacked-crooked.com/a/a92dbf35021f8758 – GManNickG Jan 07 '18 at 00:20