digitalmars.D.learn - Overloading opEquals
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (87/87) Apr 09 2010 I am trying to implement a string-like class. I actually have such a
I am trying to implement a string-like class. I actually have such a class that compiles and works with 2.037; but not I think since 2.041. I have problems implementing opEquals for this class. A simplified version of the issue is here. This code compiles and works with 2.043, but I have questions below :) import std.stdio; import std.algorithm; import std.conv; class C { dchar[] chars; this(dstring chars) { // Own characters this.chars = chars.dup; } override bool opEquals(Object o) const { auto that = cast(C)o; return (that !is null) && equal(chars, that.chars); } bool opEquals(const char[] chars) const { return equal(this.chars, chars); } bool opEquals(const wchar[] chars) const { return equal(this.chars, chars); } bool opEquals(const dchar[] chars) const { return equal(this.chars, chars); } } void main() { // Separate objects auto o0 = new C("abcç\U00000ea2"d); auto o1 = new C("abcç\U00000ea2"d); // Hoping value comparisons assert(o0 == o1); assert(o0 == "abcç\U00000ea2"c); // <--- c is required; why? assert(o0 == "abcç\U00000ea2"w); assert(o0 == "abcç\U00000ea2"d); } 1) First, should I not even bother with trying to make it so flexible. Perhaps it should not be used with any D string type? 2) Being a reference type, should I not abuse opEquals like that? Perhaps I should overload is_equal() member functions instead? 3) Which opEquals should the 'string' parameter match if I remove the trailing c on the marked line? Removing that trailing c results in a compiler error: deneme.d(9780): Error: overloads const bool(const const(char[]) chars) and const bool(const const(dchar[]) chars) both match argument list for opEquals deneme.d(9780): Error: function deneme.C.opEquals called with argument types: ((string)) matches both: deneme.C.opEquals(const const(char[]) chars) and: deneme.C.opEquals(const const(dchar[]) chars) 4) How would you reduce code duplication above? Implementing opEquals as a template for char[], wchar[], and dchar[] conflicts with opEquals(Object). New function: bool opEquals(T)(T chars) const { return equal(this.chars, chars); } And the error message: deneme.d(9758): Error: template deneme.C.opEquals(T) conflicts with function deneme.C.opEquals at deneme.d(9752) 5) Then I try a single templated implementation for all comparisons: bool opEquals(T)(T chars) const { static if (is (o : Object)) { auto that = cast(C)o; return (that !is null) && equal(chars, that.chars); } return equal(this.chars, chars); } But it doesn't work, because I can't use the 'override' keyword with it and so it does not override the default implementation for Object. The asserts fail... Thank you, Ali
Apr 09 2010