Подобно C++ и Java, язык D позволяет определять шаблонные функции. Это способ создать обобщённую функцию или объект, работающий с любым типом, который компилируется с выражениями в теле функции:
auto add(T)(T lhs, T rhs) {
return lhs + rhs;
}
Параметр шаблона T
задаётся в паре скобок перед параметрами вызова функции. T
- это просто метка, которая заменяется компилятором непосредственно при инстанцировании (создании экземпляра) функции с использованием оператора !
:
add!int(5, 10);
add!float(5.0f, 10.0f);
add!Animal(dog, cat); // не скомпилируется, так как Animal не реализует оператор "+"
Шаблоны функций имеют два набора параметров: первый для compile-time (времени компиляции) аргументов и второй для run-time (времени исполнения) аргументов (не шаблонизированные функции могут принимать только run-time аргументы). Если один или более compile-time аргументов не указаны при вызове функции, компилятор пытается вывести их из списка run-time аргументов (как типы этих аргументов).
int a = 5; int b = 10;
add(a, b); // T выводится как `int`
float c = 5.0f;
add(a, c); // T выводится как `float`
Функция может иметь любое число параметров шаблона, заданных при инстанцировании с использованием синтаксиса func!(T1, T2 ..)
. Параметры шаблона могут быть любого основного типа, включая строки и числа с плавающей запятой.
В отличие от generics в Java, шаблоны в D существуют исключительно во время компиляции и генерируют высокооптимизированный код, адаптированный под конкретный набор типов, который используетя при фактическом вызове функции.
Типы struct
, class
и interface
также могут быть определены
как шаблонные типы.
struct S(T) {
// ...
}