On Fri, 30 Sep 2011 11:48:02 -0400, kenji hara <[email protected]> wrote:
2011/10/1 Steven Schveighoffer <[email protected]>:
There is a debate in a sub-thread about logical const on whether
Object.opEquals should be const or mutable.
Right now, it's mutable. This disallows comparison between const
objects
(except it is technically allowed because the compiler ignores const
correctness for this).
I think it should be const.
However, making it const disallows opEquals functions which mutate the
object (for lazy loading or caching purposes). I question that this is
a
major concern, but I have discovered an easy fix that appeases all.
If we make opEquals a template (not Object.opEquals, but the free
function
opEquals(Object lhs, Object rhs) ), then the template has access to the
full
type information of the derived object. This means that
Object.opEquals can
be exclusively const, and you can overload this with a mutable version,
and
everything just works.
I tried it out by making my copy of druntime use a template (it's
actually
very few lines change). Although I needed to use casts to compile some
parts of phobos (some opEquals calls depend on the compiler ignoring
const
guarantees as mentioned above), when compiling a simple test program, I
can
prove it works without compiler changes.
Along with the ability to have both const and non-const (and even
technically immutable) opEquals, we have the following drawbacks and
benefits:
1. template bloat. Every combination of two object types being compared
will generate a new template.
2. inlining of opEquals. Both the free function template, and possibly
a
final-declared opEquals on a dervied object could be inlined.
3. possible specialization of opEquals(MyDerivedType obj). I don't
remember
exactly the overloading rules, so this may be impossible.
4. Fixes the issue with interface comparison (see bug
http://d.puremagic.com/issues/show_bug.cgi?id=4088), not in the best
way,
but it would be better than the current situation.
What do people think?
-Steve
I think your suggestion is almost same as mine.
Discussions: https://github.com/D-Programming-Language/phobos/pull/262
Implementations:
https://github.com/D-Programming-Language/druntime/pull/72
My patch does not support #4 (interface comparison), but others are same.
Yes, you did almost exactly what I did, except I made it valid to call
mutable opEquals for two unlike objects.
That is, I think there is no point for the static if in the middle, just
do lhs.opEquals(rhs) && rhs.opEquals(lhs) for all cases.
-Steve