www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to const-overload opEquals(R)(R rhs)?

reply "Tobias Pankrath" <tobias pankrath.net> writes:
Hey,

let's say I have a simple struct and I want to give it an 
opEquals like this.

struct Point
{
     int x, y;
     bool opEquals(R)(R rhs) { return x == rhs.x && y == rhs.y; }
}


With this I can't call opEquals on const instances of Point, 
because dmd says

 bug.d(13): Error: function bug.Point.opEquals!(Point).opEquals 
 (Point rhs) is not callable using argument types (Point) const

So I overoad is with a const version of oqEquals: struct Point { int x, y; bool opEquals(R)(R rhs) { return x == rhs.x && y == rhs.y; } bool opEquals(R)(R rhs) const { return x == rhs.x && y == rhs.y; } } But the error stays the same. So why is the const version not taken into consideration? Thanks for your answers.
Aug 07 2012
next sibling parent David <d dav1d.de> writes:
Really? It compiles: http://dpaste.dzfl.pl/e0470f9a
Aug 07 2012
prev sibling next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/07/2012 06:40 AM, Tobias Pankrath wrote:

 bool opEquals(R)(R rhs) { return x == rhs.x && y == rhs.y; }
 bool opEquals(R)(R rhs) const { return x == rhs.x && y == rhs.y; }

I strongly recommend that only the const version should be defined. That would work on both mutable and immutable objects. Besides, opEquals should not modify the object anyway; that would be surprising. Ali
Aug 07 2012
prev sibling next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
On Tuesday, 7 August 2012 at 16:46:04 UTC, Ali Çehreli wrote:
 On 08/07/2012 06:40 AM, Tobias Pankrath wrote:

 bool opEquals(R)(R rhs) { return x == rhs.x && y == rhs.y; }
 bool opEquals(R)(R rhs) const { return x == rhs.x && y ==

I strongly recommend that only the const version should be defined. That would work on both mutable and immutable objects. Besides, opEquals should not modify the object anyway; that would be surprising. Ali

Design & Style aside. Shouldn't this be possible? I do have std.Tuple in mind, which can have members of any type. If one of these does not have a const opEquals, comparison is unnecessary restricted to mutable instances.
Aug 07 2012
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, August 07, 2012 15:40:18 Tobias Pankrath wrote:
 Hey,
 
 let's say I have a simple struct and I want to give it an
 opEquals like this.
 
 struct Point
 {
 int x, y;
 bool opEquals(R)(R rhs) { return x == rhs.x && y == rhs.y; }
 }
 
 
 With this I can't call opEquals on const instances of Point,
 because dmd says
 
 bug.d(13): Error: function bug.Point.opEquals!(Point).opEquals
 (Point rhs) is not callable using argument types (Point) const

So I overoad is with a const version of oqEquals: struct Point { int x, y; bool opEquals(R)(R rhs) { return x == rhs.x && y == rhs.y; } bool opEquals(R)(R rhs) const { return x == rhs.x && y == rhs.y; } } But the error stays the same. So why is the const version not taken into consideration? Thanks for your answers.

The standard way to define opEquals at this point would be to have bool opEquals(const Point rhs) {return this == rhs;} bool opEquals(const ref Point rhs) {...} I don't know if templatizing it causes problems or not. And if you can't have it work with const for some reason, then remove the const modifiers on both. But assuming that templatizing it works, since it's a template, you could probably just do one definition with auto ref: bool opEquals(R)(auto const ref rhs) const {...} There have been some discussions on adjusting how const ref and/or auto ref works which would make it so that only one signature was required even without templates, but that hasn't been sorted out yet. - Jonathan M Davis
Aug 07 2012