Szablony

edytuj

Przykłady

edytuj
module stack;

/* Szablon klasy */
/* T - typ podawany przy tworzeniu klasy */
class Stack(T)
{
private:
    /* Tablica typu T */
    T[] tab;
public:
    void push(T val)
    {
        /* Dopisanie wartości do tablicy */
        tab ~= val;
    }
    void pop()
    {
        /* Obcięcie ostatniego elementu tablicy */
        assert(!empty());
        tab.length--;
    }
    T top()
    {
        /* Zwrócenie ostatniego elementu tablicy */
        assert(!empty());
        return tab[tab.length - 1];
    }
    bool empty()
    {
        /* Sprawdzenie czy tablica ma niezerową długość */
        return tab.length == 0;
    }
}

int main(string[] args)
{
    /* Nowy stos na elementy typu int */
    auto s = new Stack!(int);
    
    /* Teraz można normalnie korzystać ze zdefiniowanych metod */

    return 0;
}
module main;

import std.stdio;

/* Szablon rekurencyjny */
/* Uniwersalna wersja */
template factorial(int n)
{
    /* Przyjmuje wartość iloczynu n i silni (n - 1) */
    const factorial = n * factorial!(n-1);
}
/* Specjalizacja dla n = 1 */
template factorial(int n : 1)
{
    /* Przyjmuje wartość 1 */
    const factorial = 1;
}

int main(string[] args)
{
    /* Wyświetlenie 4!, całość wyliczana jest w trakcie     *
     * kompilacji, więc program działa szybko, ale wartość, *
     * której silnię chcemy obliczyć musi być stała.        */
    writefln("%d! = %d", 4, factorial!(4));

	return 0;
}

Ograniczenia

edytuj
  • Parametry szablonów muszą być znane w trakcie kompilacji, nawet jeśli nie są to typy a np. wartości liczbowe.
  • Częściowo skomplikowany zapis – nie należy ich nadużywać.
  • Brak możliwości przeprowadzenia części niskopoziomowych optymalizacji klasy bez znajomości typu.