Developement Blog

Main menu

Monthly Archives: July 2013

If you are not familiar with the Non Virtual Interface idiom I recommend that you go and read about it. D takes this idiom to the next level by allowing to have tempalted methods within interfaces if they are final. This can be very powerfull and help reducing boilerplate code.

If you look at the above example you can see that the IInputStream interface has two templated methods which are final. Thos methods implement the behavior needed for arrays and value types. Then they forward the read in the correct way to readImpl. As a result implementing the IInputStream interface becomes really easy. The only method that needs to be implemented is the readImpl method as you see from the FileInStream class. The correct handling of different types only has to be implemented once, inside the interface, and all implementations don’t have to care about this anymore. You could also think of something similar for serializing data. A ISerializer interface which implementes all the needed type handling as templates and forwards it to simple protected methods. Then implementing different serialization targets (e.g. json, xml, binary, etc) would be quite easy and not require writing and testing template code anymore. A further advantage of this idiom is, that it lowers the amout of code bloat because the templates only get generated once for the interface and are reused by every implementation.

D strives to prevent implicit conversion between user defined types at all costs. This is mostly because there are so many implicit conversion rules in C++ and history has shown that implicit conversions can lead to really hard to track down bugs. But sometimes you still want a user defined type A to implicitly convert to a builtin type or user defined type B. This is possible in the D programming language using a property and the “alias this” feature.

C++

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

import std.conv;

import std.stdio;

structNumberAsString

{

privatestringvalue;

this(stringvalue)

{

this.value=value;

}

intconvHelper()

{

returnto!int(value);

}

alias convHelper this;

}

voidmain(string[]args)

{

autoa=NumberAsString("123");

intb=a;//implicit conversion happening here

writefln("%d",b);

}

The key to this idiom is the “convHelper” property. Which does the conversion and is callable without parentheses because it does not take any arguments (a property). Next we declare “alias convHelper this”. This causes the compiler to do a fallback to aliased symbol in case using the original type does not work. This way the compiler will automatically insert a call to convHelper in case our NumberAsString type can not be used directly. As a result we get our implicit conversion.

Unfortunately this does only work for a implicit conversion to a single type. Implicit conversions to multiple types are not possible because only a single alias this is allowed per type.

Meta

Privacy Preference Center

Consent Management

Close your account?

Your account will be closed and all data will be permanently deleted and cannot be recovered. Are you sure?

This website stores some user agent data. These data are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to opt-out of any future tracking, a cookie will be set up in your browser to remember this choice for one year. I Agree, Deny