Some problems with operator overloading
bearophile
bearophileHUGS at lycos.com
Sun Mar 14 07:55:41 PDT 2010
In the following little programs can you help me tell apart my errors from bugs in dmd?
(This post shows only part of the problems I have found with operator overloading).
-------------------------------
1) Error in the documentation in this page:
http://www.digitalmars.com/d/2.0/operatoroverloading.html
This:
struct S {
int opEquals(ref const S s) { ... }
}
Probably has to become like:
struct S {
const bool opEquals(ref const(S) s) { ... }
}
-------------------------------
2) This code runs:
import std.c.stdio: printf;
struct Foo {
int data;
int opEquals(T:Foo)(T other) {
printf("A");
return this.data == other.data;
}
}
void main() {
int r = Foo(5) == Foo(5);
}
But I think dmd has to raise a c error, and require something like:
const bool opEquals(T:Foo)(ref const(Foo) other) {
Or:
const bool opEquals(T:Foo)(const(Foo) other) {
etc.
-------------------------------
3) This code runs:
struct Foo {
int data;
bool opBinary(string Op:"==")(ref const Foo other) { // wrong: opEquals
return this.data == other.data;
}
bool opBinary(string Op)(ref const Foo other) if (Op == "0") { // wrong
return this.data == other.data;
}
}
void main() {}
But that can cause bugs: it's easy for programmers to forget to use opEquals instead of opBinary("==").
And generally I'd like dmd to raise an error when silly ops are defined, like that "0". It's important to avoid many bugs in the operator overloading usage.
-------------------------------
4) This program doesn't compile:
struct Foo {
int x;
Foo opUnary(string op:"++")() {
this.x++;
return this;
}
}
void main() {
Foo f = Foo(5);
f++; // line 10
}
Prints:
temp.d(10): Error: var has no effect in expression (__tmp1)
-------------------------------
5) Here an implicit cast to uint or int can be handy, to avoid the cast (to be able to create a generic "fake int" struct), is this possible?
struct Foo {
int x;
int opCast(T:int)() {
return this.x;
}
}
void main() {
Foo f = Foo(5);
auto a1 = new int[cast(int)f]; // OK
auto a2 = new int[f]; // ERR
}
Philippe Sigaud in the digitalmars.D.learn newsgroup suggests an opImplicitCast. It can be useful in other situations (but I don't know its possible bad side effects):
struct Foo {
int x;
int opCast(T:int)() {
return this.x;
}
}
void bar(int i) {}
void main() {
Foo f = Foo(5);
bar(f); // Error
}
-------------------------------
Bye,
bearophile
More information about the Digitalmars-d
mailing list