*Strong types are about better expressing your intentions, both to the
compiler and to other human developers.**
Strong typing over generic types
This implementation of strong types can be used to add strong typing over
generic or unknown types such as lambdas:
static bool performAction(T)(T x, T y) if(hasTraits!(T, Comparable)) {
return x > y;
}
Inheriting the underlying type functionalities
You can declare which functionalities should be inherited from the underlying
type. So far, only basic operators are taken into account. For instance, to
inherit from + and toString, you can declare the strong type:
alias Meter = NamedType!(double, Tag!"meter", Addable, Printable);
There is one special trait, ImplicitConvertable, that lets the strong type be
converted in the underlying type. This has the effect of removing the need to
call .get() to get the underlying value.
Named arguments
By their nature strong types can play the role of named parameters:
alias FirstName = NamedType!(string, Tag!"firstName");
alias LastName = NamedType!(string, Tag!"lastName");
void displayName(FirstName theFirstName, LastName theLastName);
// Call site
displayName(FirstName("John"), LastName("Doe"));
But the nested type argument allows to emulate a named argument syntax:
alias FirstName = NamedType!(string, Tag!"firstName");
alias LastName = NamedType!(string, Tag!"lastName");
void displayName(FirstName theFirstName, LastName theLastName);
// Call site
displayName(FirstName.argument = "John", LastName.argument = "Doe");