A Beginner's Guide to D/Templates and Generic Programming/Template Classes

Container classes are usually most useful if they can hold any kind of item. Otherwise, you would have to write a different container for each type you wanted to hold. The traditional object-oriented approach (used by Java before version 1.5) takes advantage of polymorphism. Since all classes derive from Object, a container that holds Object instances can serve as a general-purpose container. This has a number of disadvantages:


 * Primitive types (e.g. int) cannot be directly held in the container. You must write a wrapper class (such as Java's Integer) to hold such items.
 * The container is not typesafe. You must cast items from Object to their real type when removing them from the container. There are also no particular limits on the actual types of the items in the container, meaning a given container is capable of holding a random mix of types.
 * All of this up- and down-casting can have a negative impact on performance.

The simpler solution of just writing a custom container class for each type you want to hold has obvious drawbacks. (Most obviously, it does not promote code reuse.)

Template classes were originally added to C++ to solve this problem, and D's template features are based on those in C++. A library writer first writes a generic container (say, a linked list), as though any type may be contained in it. At the start of the container, the library writer puts a placeholder for the type that will be stored in it. By convention, we usually call this T. This generic class is called a template class, so called because it serves as a template for more concrete implementations.

Syntax
A template class in D looks like this:

Note the (T) after the name of the class. This is the template parameter list. To actually use the class, we must instantiate it, by saying something like:

The template parameter list can have multiple parameters in it, just like a function parameter. A parameter with just a name is taken to be a type. Attempting to pass anything other than a type to T is an error. There are four kinds of template parameters:


 * Types : The T in the example above is a type parameter.
 * Constant values : Nearly any value which can be determined at compile-time can be used as a template parameter. Value template parameters look just like function parameters, e.g. <tt>int i</tt> in a template parameter list means the template expects an integer literal or a <tt>const int</tt>.
 * Alias parameters : These parameters can accept essentially any symbol which can be determined at compile-time. This includes functions, other templates, classes, and much more. Alias parameters are declared by putting <tt>alias</tt> before the parameter's name.
 * Tuple parameters : D supports variadic templates. This is an advanced topic, and is covered later.

Example
A simple templated stack (implemented with a linked list) might look like this:

To use the above example, we might say:

Note the syntax: <tt>LinkedStack!(int)</tt>. This is a template instantiation. This tells the compiler to generate a version of the <tt>LinkedStack</tt> class where <tt>T</tt> is replaced with <tt>int</tt>. The type of the <tt>list</tt> variable in the above example is <tt>LinkedStack!(int)</tt>. The type of <tt>strList</tt> is <tt>LinkedStack!(string)</tt>. These two types are distinct from each other. In terms of inheritance, they are only related insofar as they both inherit from <tt>Object</tt>.