Defining type coercion
Jonathan M Davis
jmdavisProg at gmx.com
Sun Feb 27 16:42:33 PST 2011
On Sunday 27 February 2011 12:10:43 Peter Lundgren wrote:
> I'd like to define a type Ordinal which behaves like an int (using a struct
> or alias) that represents the 26 letters, A-Z, with the numbers 1-26.
> Then, I would like to be able to coerce between chars and Ordinals
> appropriately.
>
> chars and ints already have the ability to coerce between each other using
> the appropriate ASCII values. So, really, I'd just like to define a type
> that overrides this behavior.
>
> As far as I can tell, the place to define such rules is with opCast!, but
> I'm at a loss for how to add additional rules to built in types.
You can use opCast, but it's only for _explicit_ casting. You can use alias this
for implicit casting, but that's not going to work very well with primitive
types, because you can't derive from them and therefore can't override their
behavior. Also, you can't currently have more than one alias this per type
(though you're supposed to be able to eventually).
So, you could easily create a type which holds an integral value of some kind
and only allows the values 1 - 26, inclusive. You can make it so that functions
on it take ints or chars or whatever. You can define opCast to cast to whatever
types you want. But you _can't_ make it implicitly convertible to or from
primitive types and have _any_ control over the conversion (since alias this
with a primitive type gives you no control over it).
But then again, you can't convert implicitly between chars and ints either
unless value range propogation tells the compiler that the conversion that
you're trying to do will fit, and that's generally restricted to literals in
local context. As soon as you do anything like pass a variable to function, that
information is lost and you're going to have to cast explicitly. So, while you
_can_ implicitly cast from a char to an int, you can't generally do so from an
int to a char, so your type would be just as implicitly castable as chars and
ints except that you wouldn't be able to cast from it to an int implicitly.
D really isn't designed with allowing you to define a type which acts like other
types without casts (unless you're dealing with polymorphism). C++ allows all
kinds of implicit conversions that D explicitly disallows in order to avoid
bugs.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list