| Title: | C++ Templates, The Complete Guide |
| Authors: | David Vandevoorde and Nicolai M. Josuttis | Published: | Addison-Wesley, 2002 |
| Pages: | 552 |
| Price: | $54.99 |
Anyone who has used a vector<int> from the Standard C++ library knows that you can do a lot of things with templates without knowing much about them. You can even design your own templates yet remain ignorant on language details, and usually the templates will work as expected. In the long run, though, such ignorance is not bliss. Beyond a certain point, the unschooled template programmer will face increasing frustration and futility. Programs blow up; the compiler rolls over and dies; etc. To avoid this cruel fate, you've got to dig deeper into the mysteries of templates and C++ in general. This book is loaded with information to help you do just that.
C++ Templates, The Complete Guide is aimed at programmers who want to use templates effectively. That means a couple of different things. First, it means understanding how a template will behave, what overload or specialization will be selected in a particular context, and the requirements a template imposes upon its arguments. Once these fundamentals are acquired, using templates effectively means getting the compiler to do most of the work. The goal here is robust code, not programmer holidays. A good compiler can make a lot of decisions and validity checks before a program even runs; the trick is in getting it to do them. To use templates effectively you must learn a rather large number of language details, some bordering on the arcane and not obviously having to do with templates. That's because, in C++, everything has to do with templates. More precisely, templates interact with virtually every other feature of C++, and sometimes in surprising ways. For this reason, there is no shortcut to mastering templates; they cannot be partitioned off and studied in isolation. This is the first book I have seen that acknowledges this reality and tackles the problem head on.
The book is divided into several major sections: Basics, Templates in Depth, Templates and Design, and Advanced Applications. The Basics section begins with an introduction to function and class templates, the sort of thing you would find in most any introductory C++ book. But that's just for starters; this section provides quite a bit more. For example, one thing you usually don't find in a beginning C++ book is a six-page discussion of template template parameters. If you haven't heard of them before, don't feel bad. Until recently, template template parameters were in the realm of the esoteric, but they are now proving useful in certain Generic Programming [1] applications. This section also includes a nice introduction to the inclusion and separation models of template compilation. Although these models concern what the compiler does behind the scenes, programmers need to understand them because they affect how the source code will be structured (e.g., must the whole template definition be #included or can function template definitions go in a separate file?).
The Basics section also covers template debugging, another topic you won't find in most C++ texts. However, this subsection is disappointingly brief, comprising not even a chapter's worth of material. There are two main questions programmers ask in debugging template code: "why won't it compile?" and "why doesn't it perform as expected?" I believe the former comes up more often for most programmers. Yet this section provides only a couple techniques for answering this question. One of those "techniques" is to go wading through the compiler error messages, in search of valuable clues. This assumes that your compiler actually produces helpful diagnostics when it gags on a template; older compilers may not. Another technique is Shallow Instantiation, of which this section gives a competent, if minimal, example. I am not sure why the authors give such scant attention to debugging, as if it were not an integral part of programming; perhaps they would say that when it comes to templates, knowledge is the best debugger.
The Templates in Depth section is crammed with such knowledge, which readers will find not readily absorbed through the skin. I consider this section the most important part of the book, and the toughest reading as well. Some of the prose here actually verges on Standardese. It is probably no coincidence that one of the authors, David Vandevoorde, is a member of the C++ Standard Committee Core Language Working Group, and one of his sworn objectives in writing this book is precision. I think he may have attained it.
This section includes a meaty chapter entitled "Names in Templates," which presents a lot of detail on how a compiler looks up the names it encounters in source files. It may seem beside the point how a compiler goes about its business, but thinking like a compiler can be a very effective way to learn C++ in depth [2]. A chapter on "Instantiation" explains what happens when a ghostlike template is incarnated as a class or function, and what the compiler needs to know at this so-called point of instantiation. This chapter revisits the inclusion and separation models and gives an interesting look at how various compilers approach the difficult problem of bringing a template to life. Two more must-read chapters in this section are "Template Argument Deduction" and "Specialization and Overloading." When it comes to templates, there are just a lot of things to know about how they interact with namespaces, friends, inheritance, etc. If you devote yourself to any sections in this book, please make this section one of them. I may grouse about the authors' occasional lapses into Standardese, but I commend them for respecting their audience enough to give them the information they need, even at the risk of being perceived as dry.
The final two sections, Templates in Design and Advanced Applications, cover the wealth of new paradigms/techniques that have been built upon templates in the past few years: Generic Programming, traits, policy classes, expression templates, smart pointers, tuples, to name a few. I confess I don't really understand the distinction between these sections, or why smart pointers are grouped with Advanced Applications. (Maybe designing a smart pointer is an advanced activity, but using one is not, and smart pointers are desperately needed in many "unadvanced" applications.) Nevertheless, these sections provide an accessible introduction to the true expressive power of C++, which remains largely untapped in C++ applications. If you desire to use C++ to its fullest, you should find these sections both useful and very enjoyable.
Be forewarned: unless you are a C++ expert, this book will definitely make you work. It contains a lot of example code, most of which is straightforward, though often complex due to the subject matter. The narrative that accompanies the code is usually clear, but minimal in spots, leaving the reader to deduce a few more things than he might like. Thus, to benefit from this book, you need to have a solid grasp of C++ basics, and preferably some experience writing your own templates, however unkosher they may turn out to be.
This is an important book, and long overdue in the C++ world. The authors are both highly respected in the C++ community. David Vandevoorde I have already mentioned; Nicolai Josuttis is author of the popular book, The C++ Standard Library [3]. It appears that their scholarly vs. application-oriented personalities managed to balance each other well. This book may help pave the way for some of the now-exotic applications of templates to become commonplace. Judging from the history of C++, that is at least one way the state of the art advances.
[1] For the uninitiated, definitions of Generic Programming vary; one approximate definition is "programming with types." But like OOP, Generic Programming is also a mindset, and its practitioners share a set of core values. One of these values might be, "do as much at compile time as you can." The last section of this book serves as a good illustration of Generic Programming principles.
[2] This book is not the first publication to take this approach. Longtime CUJ readers may recall that Dan Saks did the same thing in his former columns, "Stepping Up to C++" and "C++ Theory and Practice." Another book that takes this approach, especially with virtual functions, is Inside the C++ Object Model, by Stan Lippman.
[3] Nicolai M. Josuttis. The C++ Standard Library, A Tutorial and Reference (Addison-Wesley, 1999).
Marc Briand is former Editor-in-Chief of C/C++ Users Journal. He currently develops ATE (Automated Test Equipment Software) for the Aerospace industry. He can be reached at marcbriand@cs.com.