13.1. Introduction To Templates

Time: 00:03:15 | Download: Large, Large (CC), Small | Streaming, Streaming (CC) | Slides (PDF)

The C Programming Language is deliberately small and simple, making it relatively easy for programmers to port the compiler to new systems. Programs often use the arithmetic operations (+, -, *, /, and &), but they too are small and simple. Alternatively, the sqrt, pow, and similar functions are more complex but used less often, making them better suited for inclusion as library functions. Library functions are often tied tightly to specific data types, frequently requiring programs to cast their data to or from the function's types.

double	sqrt(double x);
 
float		sqrtf(float x);
long double	sqrtl(long double x);
(a)(b)
The evolution of the sqrt function. The original version of the C Programming language, often called K&R C for its implementors Brian Kernighan and Dennis Ritchie, was not governed by any standards body. The American National Standards Institute (ANSI) formally adopted a C standard in 1989, often called C89 or ANSI-C.
  1. The ANSI C89 standard specified the single sqrt function included as part of the language's library from its beginning. This function only processed double data, requiring type casts to deal with other data types.
  2. The ANSI C99 standard added two more versions of the square root function with distinct names encoding the data types they process.
double		sqrt(double x);
float		sqrt(float x);
long double	sqrt(long double x);
 
double		sqrt(double x);
float		sqrt(float x);
long double	sqrt(long double x);
double		sqrt(T x);
(a)(b)
The ANSI C++98 and C++11 standards. Unlike C, C++ allows programmers to overload functions, enabling C++ compilers to refer to them with a single name.
  1. The first ANSI C++ standard, C++98, began with three sqrt prototypes.
  2. The most recent standard addressing the sqrt function, C++11, looks like it added one more, rather strange prototype. However, the red T is a generalized data type matching any integral type, including int, long, char, wchar_t, bool, etc. This prototype is an example of a template function. The next section begins our detailed exploration of templates with functions like this example.

C++ is an extensible language, meaning that programmers can add new data types to their C++ programs without modifying the compiler or the language's syntax. C++ allows programmers to create new types with enumerations, structures, and classes. Although extensibility is a powerful feature, it makes creating library functions challenging. Data structures effectively illustrate the challenge.

The operations necessary to manage a data structure (e.g., insert, search, remove, etc.) are largely independent of the saved and organized data. Data independence makes data structures good candidates for inclusion in programming libraries, but only if programmers can generalize the data they save. C programs use void pointers as a general data type, which works but is clumsy, potentially confusing, and error-prone. To "cleanly" generalize the data, we need a programming mechanism that embraces C++'s extensibility and integrates more seamlessly into its existing features. Ideally, we want a mechanism that allows us to separate the organizational and data manipulation operations. Containers (called collections in Java) are data structures that store and organize data, demonstrating the separation.

Linked lists and binary trees are familiar container examples. Containers like binary trees organize the contained data by value. For example, if each data item is a student record, the container can organize it by name or ID. Formally, such data must be orderable, and in object-oriented programs, the data class itself typically provides the ordering function as a member. Templates allow programmers to create container classes with all the necessary organizational operations without regard to the stored data type. Programmers use a template variable name, often T, as a placeholder whenever the code refers to the saved or contained data type. During the compilation process, the compiler replaces the placeholder name with a program-supplied type name. We explore template classes in the third chapter section.

Although the implementing mechanisms are different, C++ templates look and behave like Java's generic classes, solving the same problems. However, C++ is a hybrid language that supports both the procedural and the object-oriented programming paradigms - where Java only supports the object-oriented paradigm. As a consequence, C++ programmers can also use templates with non-member functions.