Professional C__ - Marc Gregoire [330]
How to write customizations of your class templates for specific types
How to combine templates and inheritance
How to write function templates
How to make template functions friends of template classes
How to write template aliases
C++ provides language support not only for object-oriented programming, but also for generic programming. As discussed in Chapter 4, the goal of generic programming is to write reusable code. The fundamental tools for generic programming in C++ are templates. Although not strictly an object-oriented feature, templates can be combined with object-oriented programming for powerful results. Many programmers consider templates to be the most difficult part of C++ and, for that reason, tend to avoid them.
This chapter provides the code details for fulfilling the design principle of generality discussed in Chapter 4 and used during the discussion of the standard template library in Chapters 11 through 17.
The next chapter delves into some of the more advanced template features, including:
The three kinds of template parameters and their subtleties
Partial specialization
Function template deduction
How to exploit template recursion
Variadic templates
Metaprogramming
OVERVIEW OF TEMPLATES
The main programming unit in the procedural paradigm is the procedure or function. Functions are useful primarily because they allow you to write algorithms that are independent of specific values and can thus be reused for many different values. For example, the sqrt() function in C and C++ calculates the square root of a value supplied by the caller. A square root function that calculated only the square root of one number, like four, would not be particularly useful! The sqrt() function is written in terms of a parameter, which is a stand-in for whatever value the caller passes. Computer scientists say that functions parameterize values.
The object-oriented programming paradigm adds the concept of objects, which group related data and behaviors, but does not change the way functions and methods parameterize values.
Templates take the concept of parameterization a step further to allow you to parameterize on types as well as values. Types in C++ include primitives such as int and double, as well as user-defined classes such as SpreadsheetCell and CherryTree. With templates you can write code that is independent not only of the values it will be given, but also of the types of those values. For example, instead of writing separate stack classes to store ints, Cars, and SpreadsheetCells, you can write one stack class definition that can be used for any of those types.
Although templates are an amazing language feature, templates in C++ are syntactically confusing, and many programmers overlook or avoid them.
This chapter will teach you about template support in C++ with an emphasis on the aspects that arise in the STL. Along the way, you will learn about some nifty features that you can employ in your programs aside from using the standard library.
CLASS TEMPLATES
Class templates define a class where the types of some of the variables, methods and/or parameters to the methods are specified as parameters. Class templates are useful primarily for containers, or data structures, that store objects. This section uses a running example of a Grid container. In order to keep the examples reasonable in length and simple enough to illustrate specific points, different sections of the chapter will add features to the Grid container that are not used in subsequent sections.
Writing a Class Template
Suppose that you want a generic game board class that you can use as a chessboard, checkers board, Tic-Tac-Toe board, or any other two-dimensional game board. In order to make it general-purpose, you should be able to store chess pieces, checkers pieces, Tic-Tac-Toe pieces, or any type of game piece.
Coding without Templates
Without templates, the best approach to build a generic game board is to employ polymorphism to store generic GamePiece objects. Then, you could subclass the pieces