Skip to content
Templates
step 1/5

Reading — step 1 of 5

Learn

~1 min readTemplates and Ranges

D's templates are like C++ generics but cleaner.

Template function:

T square(T)(T x) {
    return x * x;
}

square!int(5);     // explicit
square(5);          // T inferred
square(3.14);       // T = double

The (T) is the template parameter list. (T x) is the runtime parameter list. The ! operator selects template parameters explicitly.

Template struct:

struct Pair(A, B) {
    A first;
    B second;
}

auto p = Pair!(string, int)("Ada", 36);

Constraints — restrict T at compile time:

T max(T)(T a, T b) if (is(typeof(a < b))) {
    return a < b ? b : a;
}

The if (...) is a template constraint — checked at compile time. is(typeof(...)) is the standard way to ask "does this expression compile?"

static if — compile-time branching inside templates:

T process(T)(T x) {
    static if (is(T == int)) {
        return x * 2;
    } else static if (is(T == string)) {
        return x ~ "!";
    } else {
        return x;
    }
}

Compile-time function execution (CTFE) — D evaluates eligible functions at compile time:

enum factorial = factorial(5);   // computed during compilation

D templates are turing-complete and run at compile time — used heavily in Phobos (D's standard library).

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…