Templates

24.1 Function Templates

T maxOf(T)(T a, T b) { return a > b ? a : b; }
writeln(maxOf(3, 7), maxOf("a", "b"), maxOf!double(1, 2.5));

auto sum(R)(R range) { typeof(range[0]) t = 0; foreach (x; range) t += x; return t; }

24.2 Struct and Class Templates

struct Stack(T)
{
    private T[] items;
    void push(T x) { items ~= x; }
    T pop() { auto x = items[$ - 1]; items = items[0 .. $ - 1]; return x; }
    bool empty() const { return items.length == 0; }
}
Stack!int s;
s.push(1);
Stack!(string) ss;

class Box(T) { T value; this(T v) { value = v; } }
auto b = new Box!int(5);

24.3 Template Parameter Kinds

template Foo(T) {}                     // type parameter
struct Buffer(size_t N) { ubyte[N] data; }    // value parameter
auto apply(alias fun, T)(T x) { return fun(x); }   // alias parameter (symbols, lambdas)
void variadic(Args...)(Args args) {}   // sequence parameter
struct Pair(T, U = T) {}               // default argument
template isInt(T : int) { enum isInt = true; }   // specialization
writeln(apply!(x => x * 2)(5));
Buffer!256 buf;

24.4 Eponymous Templates

template isNumericType(T)
{
    enum isNumericType = is(T : long) || is(T : real);   // same name → the template "is" the value
}
static assert(isNumericType!int);

enum isPositive(int n) = n > 0;          // shorthand enum template
alias Ptr(T) = T*;                       // alias template

24.5 Template Instantiation and Inference

IFTI (Implicit Function Template Instantiation) infers types from arguments.

auto ref parameters, template this parameters, and typeof(this).