Named Template Constraints

We will explore the named template constraints in this lesson.

We'll cover the following

Named template constraints

Sometimes, the constraints are complex, making it hard to understand the requirements of template parameters. This complexity can be handled by an idiom that effectively gives names to constraints. This idiom combines four features of D:

  • anonymous functions
  • typeof
  • is expression
  • eponymous templates

Let’s see this in a function template that has a type parameter. The template uses its function parameter in specific ways:

void use(T)(T object) { 
    // ...
    object.prepare();
    // ...
    object.fly(42);
    // ...
    object.land();
    // ...
}

As is obvious from the implementation of the template, the types that this function can work with must support three specific function calls on the object: prepare(), fly(42), and land().

One way of specifying a template constraint for that type is by the is and typeof expressions for each function call inside the template:

void use(T)(T object)
    if (is (typeof(object.prepare())) &&
        is (typeof(object.fly(1))) &&
        is (typeof(object.land()))) { 
    // ...
}

We will explain that syntax below. For now, accept that the whole construct of is (typeof(object.prepare())) means whether the type supports the .prepare() call.

Although such constraints achieve the desired goal, sometimes they are too complex to be readable. Instead, it is possible to give a more descriptive name to the whole constraint:

void use(T)(T object)
        if (canFlyAndLand!T) {
    // ...
}

That constraint is more readable because the fact that the template is designed to work with types that can fly and land is clearer.

Such constraints are achieved by an idiom that is implemented similar to the following eponymous template:

Get hands-on with 1200+ tech skills courses.