The C Programming Language was deliberately designed to be small and simple to make it easy for programmers to port the compiler to new systems.1 Consequently, it implements fundamental operations like assignment, loops, and function calls as language primitives, but it but relegates complex, less frequently used operations like sqrt and pow to library functions that programmers can implement once the compiler is functional. C 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) |
double data, requiring type casts to deal with other data types.
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) |
double.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.
Calculating the square root of a value suggests that it is numeric in nature. That is, the sqrt(T x) function requires that T is an unspecified integral type. Imagine that a program specifies a class named number_with_knobs_on.2 Programs can use the generalized square root function with instances of the class, if the class supports an automatic conversion to an integral type. Providing the number_with_knobs_on class with an overloaded conversion operator satisfies this requirement.
Data structures are another, perhaps more easily understood, example. The operations necessary to manage most data structures (e.g., insert, search, remove, etc.) are independent of the data they store and organize, while others require an ordering function. For example, the Actor 5 demonstration introduced a circularly linked list named CList that could only store instances of the Person class. To further demonstrate polymorphism, it organized the objects alphabetically by name. C programs use void pointers as a general data type, which works but is clumsy, potentially confusing, and error-prone. Alternatively, templates provide a clear generalizing mechanism using a template variable, often T, as a placeholder whenever the code refers to the generalized type, fully embracing C++'s extensibility. During the compilation process, the compiler replaces the template variable with a program-supplied type name.