This chapter explains what templates are and how you can use them to write more efficient and robust code.
Templates are mechanisms for generating functions and classes based on type parameters. You use templates to design a single class that operates on data of many types, instead of having to create a separate class for each type.
For example, you can use a function template to create a set of functions that apply the same algorithm to different data types; you can use a class template to develop a set of type-safe container classes.
This chapter shows you how to define and use class and function templates and how to use templated collection classes.
Objectives
After completing this chapter, you will be able to:
® Describe the advantages of using function and class templates.
® Describe the differences between function templates and class templates.
® Instantiate and override a function template.
® Instantiate a class template.
® Use a template to create a type-safe collection of objects.
A developer's programming model often consists of data and algorithms. In the C++ language, a template is a powerful mechanism that you can use to parameterize data. You can abstract data in function and class definitions. Templates are useful for classes and functions that generalize to arbitrary types, including built-in types such as integers and doubles, library-defined types such as the MFC type CString, and user-defined types.
This section includes the following topics:
A template is an efficient language mechanism for providing groups of closely related classes and functions. Each class or function differs from other classes or functions in the group by the data types that are specified when the template is used. For example, when you use a class template that defines an array, you specify the data type that the array can contain.
A template definition resembles a function or class definition, except that a template definition is prepended with a template tag and a parameter list. You can parameterize built-in data types, such as char and double, as well as user-defined class types. You can specify multiple parameters; however, an empty parameter list is not valid.
A template is used when it is declared with a specific data type. The compiler creates a class or function from that template (as an intermediate step) and then instantiates the construct at the point where the code is used.
A template works in much the same way as a macro. However, unlike a macro, a template enables all the type-checking capabilities of the compiler. For example, the following macro defines the area of a square given the length of a side.
#define SquareArea(s) s*s
This will work for simple cases but it will fail with more complex cases, as in the following example code:
int side= 10;
int area;
area = SquareArea(side); // OK: area is 100
area = SquareArea(side+1); // Error: area is 21, should be 121
A template version of the same functionality looks like the following example code:
template< class T >
T SquareArea(T s)
{ return s*s; }
The template version works correctly on all cases:
side = 10;
area = SquareArea(side+1) // OK: 121
Templates offer several benefits.
First, templates maximize reuse of source code and enforce strong type-checking. You can use a single template to handle any number of arbitrary data types. You can also handle arbitrary data types by converting to and from void pointers (void*), but this approach defeats the benefits of the C++ compiler's type-checking capability.
Templates also offer speed and size optimizations. When you use templates, the compiler instantiates only the code that is needed, so the code footprint is sharply reduced. The compiler can also embed template functions within other code; this optimization removes the cost of a function call, which can be significant for a tightly executing loop.
Function Templates
You use a function template to specify a set of functions that are based on the same source code but act on different data types. The compiled code for each function is generally different for each different data type, but the compiler will optimize where appropriate.
For example, the following illustration shows how you can define a function template for a family of swap functions that work with int and CString data types.
Class Templates
A class template provides a mechanism for abstracting user-defined data types as well as the associated member functions acting on that data. The following illustration shows a class template that uses two different data types — a string and a double.
Collection Templates
Collection templates are a subset of class templates. The methods of collection classes can be applied to any data type.
You can use collection templates to create data structures such as indexed arrays, linked lists, and associative arrays.
Instantiating Function or Class Templates
Template instantiation is a two-step process. The steps differ depending on whether you use a function template or class template.
Class templates are first instantiated to a class and then to an object.
When you instantiate a function template, first a specified data type is bound to the templated function, and then the function is compiled in the same manner that a standard function is compiled.
No comments:
Post a Comment