On 7/10/12 10:33 PM, Jonathan M Davis wrote:
Yeah. It seems to me that a reasonable approach would be to give Object two
versions of opEquals, opCmp, toString, and toHash - a const and non-const
version of each. The non-const version then calls the const version. So, the
normal thing to do is have your class work with const and override the const
version. If the non-const version on Object gets called, then the const
version in the derived class gets called, and if the derived type is used
directly, then it'll always use the const version, because that's what the
derived type has.

On the other hand, for a class which doesn't work with const, it does this:

1. Override the non-const versions of opEquals, opCmp, toString, and toHash,
giving them the implementations which you want.

2. Override the const versions of opEquals, opCmp, toString, and toHash and
make their bodies assert(0).

That way, those 4 functions can be used normally as long as the object isn't
assigned to a const reference, and if it is, then you get an Error.

I was a long-time proponent of this. It's less exciting than it may seem actually.

(a) Classes that work with const just fine incur one extra virtual call. I think this can be avoided by having the compiler plant the same pointer for the const and non-const version in the vtable.

(b) Classes that can't do as little as one of these four operations without mutating the object are completely excluded from the immutability system, even if they'd otherwise benefit from it. Even those that don't "care" they need to actively _work_ on not caring, which doesn't sit well.

So I don't see this as a viable solution to people who are fine with const, but would like to use e.g. some lazy computation.


Andrei

Reply via email to