Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'mutable' variable mutable only by one of the const methods?

Tags:

c++

today I have learned about the mutable keyword in C++ and would like to use it in my code.

I have a class with many const methods and one of them should be able to modify some of the object's variables (conserving the logical state of the object). However I don't want to let all the const methods to modify the variable, only the selected one. Is there any way of doing that? Maybe with const_cast?

(The code I am talking about is an implementation of the Union-Find structure. The Find operation does not change the logical state of the structure (it only searches for a root of a tree), but changes the physical state by doing so-called path compression)

Thanks!

EDIT: I have added an excerpt from the code I am referring to:

class UnionFind {
  public:
    void Union(int a, int b) {...}

    int Find(int x) const {
      // logically, this method is const
      while(x != parents[x]) {
        // path compression
        // the next three lines modify parents and sizes, 
        // but the logical state of the object is not changed
        sizes[parents[x]] -= sizes[x];
        sizes[parents[parents[x]]] += sizes[x];
        parents[x] = parents[parents[x]];

        x = parents[x];
      }
      return x;
    }

  int someOtherMethodThatAccessesParents() const {
    // this method does access parents, but read only.
    // I would prefer if parents behaved like if it was 
    // not 'mutable' inside this method
    ...
  }

  private:
    // these have to be mutable if I want the Find method
    // to be marked const (as it should be)
    // but making them mutable then does not enforce 
    // the physical non-mutability in other const methods :(
    mutable std::vector<int> parents;
    mutable std::vector<int> sizes;
 };
like image 481
serycjon Avatar asked May 27 '26 06:05

serycjon


1 Answers

On first glance this can't be achieved unless you use a nasty const_cast. But don't do that since the behaviour on attempting to modify a variable following a const_cast that was originally declared as const is undefined.

However, it might be feasible to achieve what you want using friendship since that can be controlled on a function by function basis whereas mutability, as you correctly point out, cannot be.

Put the variable you want to modify in a base class and mark it private. Perhaps provide a "getter" function to that member. That function would be const and would probably return a const reference to the member. Then make your function a friend of that base class. That function will be able to change the value of that private member.

like image 191
Bathsheba Avatar answered Jun 02 '26 07:06

Bathsheba