How will we fix opEquals?

Jason House jason.james.house at gmail.com
Thu Feb 10 09:24:02 PST 2011


Steven Schveighoffer Wrote:

> On Thu, 10 Feb 2011 09:15:36 -0500, Jason House  
> <jason.james.house at gmail.com> wrote:
> 
> > Don Wrote:
> >
> >> Andrei once stated a worthy goal: as far as possible, const should be
> >> opt-in: it should be possible to code without requiring const on  
> >> everything.
> >>
> >> opEquals() is in conflict with this, since it is a member function of
> >> Object.
> >>
> >> (1) If it is a const member function, then it will have a viral effect
> >> on all objects -- any function called by opEquals will have to be marked
> >> const.
> >> (2) If it is not const, then const objects cannot be compared!
> >>
> >> Currently, it's not const,  but the problem isn't visible because of
> >> compiler bug 5080. (Same problem applies to opCmp).
> >>
> >> How will we break this dilemma?
> >
> > class LazyObject{
> >   bool OpEquals(LazyObject);
> > }
> >
> > class Object : LazyObject{
> >   override bool OpEquals(LazyObject) const;
> >   bool opEquals(const Object) const;
> > }
> >
> > By default, all classes derive from Object, but those that want to  
> > ignore viral const or implement lazy calculations can derive from  
> > LazyObject.
> 
> This doesn't work.  What if the user overrides one and not the other?  Or  
> the semantics are different?  Then const objects compare differently than  
> non-const ones.
> 
> -Steve

You can never stop programmers from writing incorrect code...

The way I envision this, "bool opEquals(LazyObject) const" would rarely be overridden. I would recommend writing it in terms of the other function. Something akin to the following:
bool OpEquals(LazyObject o) const{
  auto x = cast(const Object) o;
  if (x is null)
    return false;
  return (this==x);
}

There may be a better way to implement that, but the general idea is that 99% of people overriding a class's OpEquals will return false for anything that is not an Object.

I don't know D's overloading rules well enough...
Which overload would be called for the following code?
Object o1;
Object o2;
o1 == o2;

Ideally, it'd call the const(Object) overload and not the LazyObject overload. I have a sneaking suspicion that D would consider it ambiguous and give a compile error. I'm sure that could be fixed if people like this solution.


More information about the Digitalmars-d mailing list