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