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 +
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`
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 string
s 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) {
// ...
}