Шаблоны являются основой обобщённого программирования, которое включает в себя написание кода таким образом, чтобы он не зависел от какого-либо конкретного типа.
Шаблон представляет собой схему или формулу для создания обобщённого класса или функции.
Шаблоны – это возможность, которая позволяет описывать код как образец, по которому компилятор автоматически сгенерирует программный код. Части исходного кода могут быть оставлены незаполненными для компилятора, пока эта часть не будет использована в программе. Компилятор заполняет недостающие части.
Укажу здесь, что я переводил Учебное пособие по шаблонам языка D. Для глубокого изучения этой не самой простой темы и некоторых смежных тем оно лучше подходит – прим. пер.
Определение функции в качестве шаблона оставляет один или несколько используемых типов как неопределённые, впоследствии они будут выведены компилятором. Типы, которые остаются неопределёнными, задаются в списке параметров шаблона, который находится между именем функции и списком параметров функции. По этой причине шаблоны функций имеют два списка параметров:
import std.stdio; void print(T)(T value) { writefln("%s", value); } void main() { print(42); print(1.2); print("test"); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
42 1.2 test
Может присутствовать несколько параметров-типов. Это показано в следующем примере.
import std.stdio; void print(T1, T2)(T1 value1, T2 value2) { writefln(" %s %s", value1, value2); } void main() { print(42, "Test"); print(1.2, 33); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
42 Test 1.2 33
Так же, как мы можем определить шаблоны функций, также мы можем определить шаблоны классов. Следующий пример определяет класс Stack и реализует обобщённые методы push и pop для элементов из стека.
import std.stdio; import std.string; class Stack(T) { private: T[] elements; public: void push(T element) { elements ~= element; } void pop() { --elements.length; } T top() const @property { return elements[$ - 1]; } size_t length() const @property { return elements.length; } } void main() { auto stack = new Stack!string; stack.push("Test1"); stack.push("Test2"); writeln(stack.top); writeln(stack.length); stack.pop; writeln(stack.top); writeln(stack.length); }
Когда вы скомпилируете и выполните эту программу, она возвратит следующий результат:
Test2 2 Test1 1