Templates

D allows defining templated functions similar to C++ and Java which is a means to define generic functions or objects which work for any type that compiles with the statements within the function's body:

auto add(T)(T lhs, T rhs) {
    return lhs + rhs;
}

The template parameter T is defined in a set of parentheses in front of the actual function parameters. T is a placeholder which is replaced by the compiler when actually instantiating the function using the ! operator:

add!int(5, 10);
add!float(5.0f, 10.0f);
add!Animal(dog, cat); // won't compile; Animal doesn't implement +

Implicit Template Parameters

Function templates have two parameter sets - the first is for compile-time arguments and the second is for run-time arguments. (Non-templated functions can accept only run-time arguments). If one or more compile-time arguments are left unspecified when the function is called, the compiler tries to deduce them from the list of run-time arguments as the types of those arguments.

int a = 5; int b = 10;
add(a, b); // T is to deduced to `int`
float c = 5.0;
add(a, c); // T is deduced to `float`

Template properties

A function can have any number of template parameters which are specified during instantiation using the func!(T1, T2 ..) syntax. Template parameters can be of any basic type including strings and floating point numbers.

Unlike generics in Java, templates in D are compile-time only, and yield highly optimized code tailored to the specific set of types used when actually calling the function

Of course, struct, class and interface types can be defined as template types too.

struct S(T) {
    // ...
}

In-depth

Advanced

rdmd playground.d