Difference between revisions of "Implicit conversions in user types"

From D Wiki
Jump to: navigation, search
(Created page with "Part of D's philosophy is that the gap between builtin types like int, char, and string, and user-defined types, like BigNum, should be as narrow as possible. This is especial...")
 
(it's a technique, not a trick -- it's what alias this was designed for)
Line 24: Line 24:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
This trick works because '''alias X this''' means that the struct MyInt will behave like X, except that it adds a few members of its own. In this case, X is toInt, which happens to be an int property, which means that MyInt should behave like an int. When MyInt is passed to func, the compiler evaluates the property toInt, but since that's a @property, this turns into a function call to toInt() that performs the desired conversion. Implicit conversion to int is thus achieved.
+
This technique works because '''alias X this''' means that the struct MyInt will behave like X, except that it adds a few members of its own. In this case, X is toInt, which happens to be an int property, which means that MyInt should behave like an int. When MyInt is passed to func, the compiler evaluates the property toInt, but since that's a @property, this turns into a function call to toInt() that performs the desired conversion. Implicit conversion to int is thus achieved.
  
This trick can be used to implicitly convert to any desired type.
+
This technique can be used to implicitly convert to any desired type.
  
 
==Credits==
 
==Credits==
  
This trick is due Walter Bright, who demonstrated it in his half-precision float implementation.
+
This technique is due Walter Bright, who demonstrated it in his half-precision float implementation.

Revision as of 02:26, 15 December 2012

Part of D's philosophy is that the gap between builtin types like int, char, and string, and user-defined types, like BigNum, should be as narrow as possible. This is especially true for user-defined numeric types, which ideally should blend into the language's expression syntax so that, besides actually declaring a variable of the user-defined type, it can be used just as if it were a built-in type.

An important component of narrowing the gap between builtin and user-defined types is permitting implicit conversions between the user-defined type and the builtin types. For example, it is desirable for a custom integer type, say MyInt, to implicitly convert to the builtin int type, so that if you have a function func that expects an int, you can directly pass MyInt to func without having to explicitly call a conversion function to convert MyInt to int.

One way to accomplish this implicit conversion is to use D's alias this feature:

struct MyInt
{
    @property int toInt()
    {
        // perform necessary computations to convert MyInt to int
        return convertedValue;
    }

    alias toInt this;
}

void func(int x) { ... } // N.B. expects an int

auto mi = MyInt();
func(mi.toInt);   // this works, but is ugly
func(mi);         // this also works, because of alias this

This technique works because alias X this means that the struct MyInt will behave like X, except that it adds a few members of its own. In this case, X is toInt, which happens to be an int property, which means that MyInt should behave like an int. When MyInt is passed to func, the compiler evaluates the property toInt, but since that's a @property, this turns into a function call to toInt() that performs the desired conversion. Implicit conversion to int is thus achieved.

This technique can be used to implicitly convert to any desired type.

Credits

This technique is due Walter Bright, who demonstrated it in his half-precision float implementation.