When both versions are available, the logic is pretty straightforward:
const version is called for
const objects, non-
const version is called for non-
const objects. That’s all.
In your code sample
a is a non-
const object, meaning that the non-
const version is called in all cases. The
const version is never called in your sample.
The point of having two versions is to implement “read/write” access for non-
const objects and only “read” access for
const objects. For
const version of
operator  is called, which returns a
const double & reference. You can read data through that const reference, but your can’t write through it.