Overloading opEquals
Ali Çehreli
acehreli at yahoo.com
Fri Apr 9 00:49:32 PDT 2010
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
More information about the Digitalmars-d-learn
mailing list