www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Overriding opEquals in classes, for comparison with things that aren't

reply pineapple <meapineapple gmail.com> writes:
With this bit of code, the first method seems to work fine - 
things go as expected. But I get a compile error with the second 
method, and I'm not sure how else to write this.

     override bool opEquals(Object value) const{
         return this.equals(cast(typeof(this)) value);
     }
     override bool opEquals(T)(T value) const if(isNumeric!(T)){
         return this.equals(value);
     }

The compile errors I get look like this:

C:\path\to\file.d(477): Error: function 
units.quantity.opEquals!int.opEquals cannot override a 
non-virtual function
C:\path\to\file.d(519): Error: template instance 
units.quantity.opEquals!int error instantiating

How can I revise this so that I can override comparison operators 
for things other than class instances?
Jan 29
next sibling parent pineapple <meapineapple gmail.com> writes:
It also occurred to me to do something like this, but it isn't 
accepted either.

     override bool opEquals(T)(T value){
         return this.equals(value);
     }
Jan 29
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 29 January 2016 at 15:00:59 UTC, pineapple wrote:
 With this bit of code, the first method seems to work fine - 
 things go as expected. But I get a compile error with the 
 second method, and I'm not sure how else to write this.

     override bool opEquals(Object value) const{
         return this.equals(cast(typeof(this)) value);
     }
     override bool opEquals(T)(T value) const if(isNumeric!(T)){
         return this.equals(value);
     }

 The compile errors I get look like this:

 C:\path\to\file.d(477): Error: function 
 units.quantity.opEquals!int.opEquals cannot override a 
 non-virtual function
 C:\path\to\file.d(519): Error: template instance 
 units.quantity.opEquals!int error instantiating

 How can I revise this so that I can override comparison 
 operators for things other than class instances?
The first implementation is fine because you're overriding the implementation in the base class (Object). However, the second one fails because it's a template. Templates are non-virtual and cannot override anything. Even if you could, there is no such implementation in Object and, therefore, nothing to override. Templated functions can be used as overloads, though, but I'm not sure off the top of my head if the compiler accepts templated opEquals on classes at all. My guess is no, but you can find out by removing the override from the template declaration. If not, you should be able to implement non-templated overloads for the types you're interested in (without the override keyword, mind you, since they won't be overriding anything).
Jan 29
parent pineapple <meapineapple gmail.com> writes:
On Friday, 29 January 2016 at 15:13:45 UTC, Mike Parker wrote:
 The first implementation is fine because you're overriding the 
 implementation in the base class (Object). However, the second 
 one fails because it's a template. Templates are non-virtual 
 and cannot override anything. Even if you could, there is no 
 such implementation in Object and, therefore, nothing to 
 override.

 Templated functions can be used as overloads, though, but I'm 
 not sure off the top of my head if the compiler accepts 
 templated opEquals on classes at all. My guess is no, but you 
 can find out by removing the override from the template 
 declaration. If not, you should be able to implement 
 non-templated overloads for the types you're interested in 
 (without the override keyword, mind you, since they won't be 
 overriding anything).
Hm, I should've thought to try that. I was able to get things working as I wanted them to by doing this: override bool opEquals(Object value) const{ return this.equals(cast(typeof(this)) value); } bool opEquals(T)(T value){ return this.equals(value); }
Jan 29