www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How do you overload opEquals?

reply "Dale Matthews" <dem7w2 mst.edu> writes:
I'm brand new to D and I'm taking on a project. In the midst, 
I've overloaded a whole load of operators for my Vec3 class. Most 
seem to be working (I haven't tested them all yet) but opEquals 
is refusing to be called. I've followed the guidelines here: 
http://dlang.org/operatoroverloading.html#equals

class Vec3
{
public:
	float x, y, z;
	this(float xVal, float yVal, float zVal) { x = xVal, y = yVal, z 
= zVal; }
	bool opEquals()(auto ref const Vec3 v) const
	{
		debug writeln("bool opEquals(Vec3) called");
		return x == v.x && y == v.y && z == v.z;
	}
};
unittest
{
	Vec3 v = new Vec3(5, 10, 15);
	Vec3 v2 = new Vec3(5, 10, 15);
	//if(v.opEquals(v2))                      //this works great!
	if(v == v2)                                   //idk where this 
goes off to but it returns false
		writeln("FINALLY");
	else
		writeln("try again?");
}

I've tried many variations of auto ref and const (although I'm 
not sure how the function is different for each variation), and 
it still doesn't get called. I feel like I'm missing something 
simple.
Nov 19 2013
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 19 November 2013 at 20:59:31 UTC, Dale Matthews wrote:
 I feel like I'm missing something simple.
opEquals doesn't work on classes with class references. It doesn't call a method with obj = other_obj, it just rebinds the reference. If you want full control over opEquals, it'll have to be a struct instead of class.
Nov 19 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 19 November 2013 at 21:05:23 UTC, Adam D. Ruppe wrote:
 opEquals doesn't work on classes with class references.
IGNORE ME, I am wrong here. I mixed up opEquals and opAssign in my head. Sorry!
Nov 19 2013
parent "Dale Matthews" <dem7w2 mst.edu> writes:
On Tuesday, 19 November 2013 at 21:22:27 UTC, Adam D. Ruppe wrote:

 IGNORE ME, I am wrong here. I mixed up opEquals and opAssign in 
 my head.

 Sorry!
Will do :]
Nov 19 2013
prev sibling next sibling parent reply "Chris Nicholson-Sauls" <ibisbasenji gmail.com> writes:
On Tuesday, 19 November 2013 at 20:59:31 UTC, Dale Matthews wrote:
 I'm brand new to D and I'm taking on a project. In the midst, 
 I've overloaded a whole load of operators for my Vec3 class. 
 Most seem to be working (I haven't tested them all yet) but 
 opEquals is refusing to be called. I've followed the guidelines 
 here: http://dlang.org/operatoroverloading.html#equals

 class Vec3
 {
 public:
 	float x, y, z;
 	this(float xVal, float yVal, float zVal) { x = xVal, y = yVal, 
 z = zVal; }
 	bool opEquals()(auto ref const Vec3 v) const
 	{
 		debug writeln("bool opEquals(Vec3) called");
 		return x == v.x && y == v.y && z == v.z;
 	}
 };
 unittest
 {
 	Vec3 v = new Vec3(5, 10, 15);
 	Vec3 v2 = new Vec3(5, 10, 15);
 	//if(v.opEquals(v2))                      //this works great!
 	if(v == v2)                                   //idk where this 
 goes off to but it returns false
 		writeln("FINALLY");
 	else
 		writeln("try again?");
 }

 I've tried many variations of auto ref and const (although I'm 
 not sure how the function is different for each variation), and 
 it still doesn't get called. I feel like I'm missing something 
 simple.
override bool opEquals (Object o) const { if ( auto v = cast( typeof( this ) ) o ) return x == v.x && y == v.y && z == v.z; return false; } You need: 1) 'override' in order to override the base class implementation. 2) 'Object' typed parameter, then cast.
Nov 19 2013
parent reply "Dale Matthews" <dem7w2 mst.edu> writes:
On Tuesday, 19 November 2013 at 21:10:57 UTC, Chris 
Nicholson-Sauls wrote:
     override bool opEquals (Object o) const {
         if ( auto v = cast( typeof( this ) ) o )
             return x == v.x && y == v.y && z == v.z;
         return false;
     }


 You need:
 1) 'override' in order to override the base class 
 implementation.
 2) 'Object' typed parameter, then cast.
Very cool, it works great! Thanks for the help, Chris. Adam, do you recommend using a struct instead of a class? I'm from C++ where structs are mainly used for PODs. It sounds handy in instances like this though: http://dlang.org/cpptod.html#structcmp
Nov 19 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 19 November 2013 at 21:25:47 UTC, Dale Matthews wrote:
 Adam, do you recommend using a struct instead of a class?
Yes, I would use a struct instead of a class here. The key question to ask in D is: do you need inheritance? If yes, use a class, if no, struct is usually better, since it is lighter weight and generally more flexible.
Nov 19 2013
parent reply "Andrea Fontana" <nospam example.com> writes:
On Tuesday, 19 November 2013 at 21:33:31 UTC, Adam D. Ruppe wrote:
 On Tuesday, 19 November 2013 at 21:25:47 UTC, Dale Matthews 
 wrote:
 Adam, do you recommend using a struct instead of a class?
Yes, I would use a struct instead of a class here. The key question to ask in D is: do you need inheritance? If yes, use a class, if no, struct is usually better, since it is lighter weight and generally more flexible.
And, of course, struct are value type, class are reference type. So, for example: int i = 0; while(++i < 10000000) { S a; // if S is a class S a = new S; a.i = 10; } it's really faster if S is a struct
Nov 19 2013
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Tuesday, 19 November 2013 at 23:58:20 UTC, Andrea Fontana 
wrote:
 And, of course, struct are value type, class are reference type.
Yeah, true in general, though it is possible to have a struct be very similar to a reference type. Consider: struct WrappedClass { Object obj; /* and whatever other methods, but no more data */ } It's still a value type, but the only member is a reference, so you can use it the same way as any other reference type; it works the same way as Object itself. So struct is flexible in the value vs reference type regard too.
Nov 19 2013
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On 11/20/2013 5:59 AM, Dale Matthews wrote:

 class Vec3
 {

      bool opEquals()(auto ref const Vec3 v) const
You don't need to use 'ref' on parameters that are classes. Unlike C++, D classes are already reference types, not value types. More like Java. Structs, OTOH, are value types. With those, a const ref parameter makes sense, but not with classes.
Nov 19 2013