Greetings
D only lets you define operator overloads in methods, unlike
C++ which lets you define overloads as functions. If you want
such an operator overload, you will have to define it as a
method.
That is all right, since for binary operators there is opBinary
and opBinrayRight. Correspondingly, I am missing opCastRight.
However, I suggest that most of the time, writing an opCast
overload is usually the wrong solution. It's often better to
write functions for type conversions instead, which can easily
be defined outside of the struct definition and used with UFCS.
So you can have say this...
ll.toBoxedInteger
... instead of this
cast(Integer) ll
In general it seems ".to" conversion is not meant to *cast* away
information. For example, the following code gives me runtime
error for trying to convert a long into an int.
void main() {
import std.conv;
int ii = 8589934592L.to!int;
}
However I would suggest that even in this case converting from
long to int is error prone, so I would just force users of your
struct to cast first from long to int, then wrap the number in
your boxed struct.
Integer(cast(int) ll)
You are much more likely to get warnings from D compilers about
the cast in the right places now. However you can go one step
further and ask yourself, do you need boxed integers at all? D
allows you to create collections of primitive types and so on,
so you might not even need a boxed type like Integer, however
there may be some use cases.
I just created Integer for the purpose of illustration. I am
working on a BitVector module. And since BitVector is a template
(with bitnum parameter), forcing the users to cast into int does
not work. Consider the case when bitnum is 48 bits.
alias BitVector!48 bitv48;
long ll;
bitv48 foo = cast(bitv48) ll; // I need cast here
Regards
- Cherry