Subject lines says it all, I think... The choice to make binary operators implementable only via this opBinary
template means it's unclear how to get virtual operators on an interface. E.g., this toy example does compile:
interface Scalar {
Scalar opBinary(string op)(Scalar rhs); // wrong
}
class Int : Scalar {
int i;
this(int i) { this.i = i; }
Int opBinary(string op)(Int rhs) if (op == "+") {
return new Int(i + this.i);
}
}
void main() {
Scalar one = new Int(1);
Scalar two = one + one;
}
but with linker errors, of course:
~[...] $ dmd scratch.d
/usr/bin/ld: scratch.o: in function `_Dmain':
scratch.d:(.text._Dmain[_Dmain]+0x2a): undefined reference to `_D7scratch6Scalar__T8opBinaryVAyaa1_2bZQtMFCQBqQBlZQi'
collect2: error: ld returned 1 exit status
Error: undefined reference to `scratch.Scalar scratch.Scalar.opBinary!("+").opBinary(scratch.Scalar)`
referenced from `_Dmain`
perhaps `.d` files need to be added on the command line, or use `-i` to compile imports
Error: linker exited with status 1
cc scratch.o -o scratch -m64 -Xlinker --export-dynamic -L/usr/lib64 -Xlinker -Bstatic -lphobos2 -Xlinker -Bdynamic -lpthread -lm -lrt -ldl
Could someone set me straight here? I just want to be able to define an interface that has some binary ops and then overload them as needed.
I am very new to D, and my goal is to learn how to solve this problem using classic, runtime, dynamic polymorphism in D (so, please don't suggest that I solve a different problem, suggest that I use a particular library, a different technique, etc.). Thanks in advance.