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…