On Friday, September 30, 2011 11:35:51 Steven Schveighoffer wrote: > 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?
Sounds good to me. Even better, it would make it possible to have opEquals be pure too, since a derived class could make it pure and then the opEquals template could be pure, allowing for the use of == in pure functions when dealing with classes. - Jonathan M Davis
