X-Men

Introduction

This C++ language never ceases to amaze me .. Something new to learn everyday, and today I learned that mutating creatures aren’t X-Men exclusive, C++ has those, too!! The first time I was mutating was actually in Swift. In Swift, struct functions are const by default, unless declared mutating. For example, the code below doesn’t even compile:

struct X { 
    var y = 0 
    func mutateY() { 
        y += 1 
    } 
} 

Anyway, mutating was found in C++, and it seems to serve a different purpose!

Injecting the Uranium

Let’s kick off with some code!

struct Nice {

   int sizeOfSharedContainer() const {
        Lock lock(_mutex);
        return _container.size();
   }

private:
    mutating Mutex _mutex;
    std::vector<int> _container;
};

Imagine the code Without the mutating keyword being there. Now, look at sizeOfSharedContainer implementation. You would have to assume that the Lock constructor takes a const& of _mutex, since the method is marked as const. Reality is, Lock needs to mutate _mutex, so other threads accessing _mutex know another thread is in the critical section! What now?!

The goal here is to still mark the method as const, since as far as the logical representation of Nice is concerned, the object didn’t change after the execution of sizeOfSharedContainer!! We mutated a mutex to ensure thread safety for a short while, then revert it back.

Lazy developers would immediately remove const from the method. Fortunately, the developer’s code I read wasn’t one of the lazy peeps. Adding mutating, as you probably guessed by now, allows us to overrule the const restriction for certain data members.

Why Haven’t I Head of It?

I guess I’ve never come across it before because it is essentially a double edged sword, much like const_cast. People use it very carefully, and it probably only makes sense once the program start to become a bit complex. Some workarounds exist, so this feature isn’t a dire need, so that’s also another reason why only few professionals use it.

Other Use Cases

Another helpful use case is lazy-loaded variables. Their getters should be marked as const, but on first access, we would have to mutate the cache variable to store the value once. Just make sure that cache variable is private!

A use case I actually thought of, and didn’t nab from the Google, is memoization. It is actually derived from the lazy loading concept, lol.

Conclusion

I need to write more interesting posts, with pics and stuff…