Slashdot Mirror


C++ Templates: The Complete Guide

nellardo writes "The book C++ Templates: The Complete Guide, by Vandevoorde and Josuttis, Addison-Wesley 2003, is an authoritative treatment of exactly what it claims: the template mechanism of C++. If you are a C++ programmer, you should have this book on your shelf. If you aren't a C++ programmer, move along -- this book is highly specific to C++, and won't be much help in understanding the template mechanisms of other languages. Of course, if you aren't a C++ programmer, you probably wouldn't even give this book a second glance in the first place." Read on for the rest of Brook's review. C++ Templates: The Complete Guide author David Vandevoorde & Nicolai M. Josuttis pages 528 publisher Addison Wesley rating 10 for C++ programmers, 0 for anyone else. reviewer Brook Conner ISBN 0201734842 summary A thorough, exhaustively complete treatment of a complex subject. An essential reference for C++ programmers and a lengthy and boring book for anyone else.

The C++ programming language is widely regarded as a good systems programming language, albeit a complex one fraught with low-level details and issues (though arguably this is what makes it good for certain kinds of systems programming). For perhaps a decade now, C++ has had a template mechanism - in programming language circles, it might more properly be called a form of parametric polymorphism. The template mechanism, like many other forms of parametric polymorphism, is potentially extremely powerful, but the complexity of C++ makes it tough to thoroughly master. That's where this book comes in.

Most likely, an experienced C++ programmer has at least used templates. If nothing else, use of the Standard Template Library (or STL) requires at least knowledge of how to use templates. If you use C++ enough to care about templates, you probably know what they are, at least roughly, and if you don't, this isn't the book from which to learn about them. It very clearly requires (and explicitly states in the introduction) that you need to know C++ before making effective use of the book.

Designing template classes, however, is another kettle of fish, and if you're in a position where you're building template classes for someone else to use, you probably need this book. Unless, like the book's authors, you moderate comp.lang.c++.moderated. If you are such a super C++ guru, you may still find this book useful - it is a truly stupendous catalog of the capabilities and subtleties of C++ templates. If nothing else, you'll find examples for well nigh every use to which you are likely to put C++ templates.

The book's strengths, then, are its authoritative and exhaustive detail. On the downside, its examples are dry and flavorless. Perhaps this is intentional, as a way to suggest how some feature can be used in a variety of situations. I prefer a combination of specific, concrete examples, followed by a generic example. The specifics motivate the need for a capability, while the generic showcases the broad, interrelated aspects of the capability. The authors didn't follow that approach. I would suspect this comes in part from their mutual roles in C++ standards bodies - a specific example could be seen as too limiting, and so were left out.

Another drawback, to my thinking, is its resolute focus on C++ to the exclusion of all other languages. Don't get me wrong - I read the title, and it's a C++ book, so I don't expect it to teach me Scheme, much less Haskell. However, I think the complexities of C++ templates might have been easier to tackle and understand with at least pointers to other ways it could have been (and has been) done. If nothing else, citations of alternative approaches would be a useful source for the motivated reader. As it is, it doesn't even deal with differences between C++ implementations - it doesn't even list GCC in the index.

All in all, though, C++ Templates: The Complete Guide is exactly what it claims to be. It's an in-depth treatment of C++ templates and how they work. It isn't a cookbook for practical applications, nor is it a guide to further in-depth exploration of parametric polymorphism. But it is definitely a handy reference for the working C++ programmer to have on her shelf. If you're a working C++ programmer, I'd recommend it. If you aren't, you might want to pass on this one.

You can purchase C++ Templates: The Complete Guide from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.

5 of 371 comments (clear)

  1. Re:Are templates always necessary? by J0ey4 · · Score: 5, Informative

    You are forgetting one of the biggest advantages to generics such as templates, speed. When templates are used much if not all of the binding is accomplished statically at compile time, when inheritance is used much if not all of the binding occurs at runtime. When you use inheritance every call to a virtual method requires a lookup to the vtable, this overhead is non-exsistent in templates. This is not an issue if you are writing bloated desktop apps in Java, but embedded or system-level applications demand the highest speeds possible.

  2. Re:Are templates always necessary? by SquareOfS · · Score: 5, Informative
    Umm . . . not sure if we're missing the point here but:

    One of the major strengths of templates is to avoid exactly the situation that Java everything-from-Object inheritance causes in collections.

    In other words, this code:

    MyObject m = (MyObject)iterator.next();
    gets boring really quickly. Templates in collections saves you all that downcasting.

    In fact, it's so useful, it's appearing in Java in JDK1.5, courtesy of JSR 14.

    But far beyond convenience when typing, the important point is that using templates or generics in collections turns the typesafety of collections into a compile-time check rather than a runtime exception. Which is a Good Thing.

  3. An excellent book, but be aware by dsplat · · Score: 4, Informative

    First, there are some significant errata (and a lot of minor typos). Get the errata list and the code for all of the examples from one of the authors at his website. Second, some of these techniques depend on features that aren't yet available in many compilers. Don't expect them all to work yet. They do discuss that in the book.

    With that said, I'm not sure that I would have rated this book a 10, but it's close enough that I'm not arguing. It is not a light read, nor should it be. This book and Andrei Alexandrescu's Modern C++ Design have convinced me that C++ templates are much more powerful, useful and complex than I realized. In fact, if I hadn't read Alexandrescu's book first, I wouldn't have thought C++ Templates was missing anything. These two books should be on the shelf of anyone who wants to use the full power of templates.

    --
    The net will not be what we demand, but what we make it. Build it well.
  4. Re:Bloat by vidarh · · Score: 4, Informative
    If you're a C++ programmer and don't use templates, you're not doing your job. If you've ever used map,vector,multimap,set,multiset,list,string,pair or most other classes from the C++ standard library, you've been using templates (yes, even "string" - string is a typedef for std::basic_string).

    You're also being left behind in the dust. Modern C++ is all about exploiting templates to simplify development, and even reduce code bloat (by making it easier to reuse common code) and increase performance (through automatic compile time generation of heavily inlined versions of algorithms).

    If you make a huge template with lots of code that could be easily generalized for all types, then you're writing a bad template: You should factor all common code into a base class and make a template that contain the few parts of the code that are type specific. On the other hand, if your code can't easily be generalized for the types you need, templates save you the tedious and error prone task of maintaining multiple versions of your code specialized for multiple types.

    In that respect templates dramatically reduce the amount of work you need to do, if applied properly.

    As mentioned above, template techniques can dramatically improve performance over a generic algorithm by providing you with an automated way of generating heavily optimized inlined versions of an algorithm. The C++ template syntax is not really ideal for this, but the benefits from using templates for this are tremendous enough to make it worthwhile. Do a search for Vandevoorde's work on expression templates, or for Alexander Alexandrescu on Google to find more, or read Alexandrescu's articles in CUJ.

    Continue to believe your prejudices if you want, but consider that if you can't use or write templates you've essentially shut yourself out of a huge segment of the C++ development job market. I would certainly never hire a "C++ developer" that don't at the very least have thorough experience with the STL, and preferrably understand how to write (and when to write) templates.

  5. Re:Bloat: O.K., I'll bite by renehollan · · Score: 4, Informative
    Templates can certainly lead to code bloat: you're telling the compiler how to generate classes (and, by extention, member and non-member functions) that are parametrized by type.

    So, instead of void Sort(int array[], size_t count) { ... } to sort an array of ints, you have template <typename T> Sort(T array[], size_t count) { ... } and the means to define a function that can sort an array of anything, with complete type-safety. Naturally, this generates a Sort function for each kind of array of things you need to sort... hmmm, there's room for improvement, no?

    If you don't get the "there's room for improvement" part, and use templates to get nice type-specific varients of common functions, you will get code bloat, and that is one of the things that give templated-code a bad reputation. But, we're Slashdotters, we're smarter than that.

    Recalling our C days, we immediately code void Sort(void *array, size_t count, int (*compare)(void *, void *)){ ... } where we pass a generic array pointer, and an additional pointer to a function that knows how to compare generic elements -- the specific call will then be something like: Sort((void *)pFoo, count, (int (*)(void *, void *))FooCompare). Gee, where did all our typesafety go? [Java programmers who are otherwise typesafety puristis grind their teeth at this point].

    If you can imagine a generic implementation, you can combine the best of both approaches: hiding the type downcasting inside the generic templated definition:

    inline void template <typename T> Sort(T array[], size_t count)
    {
    genericSort((void *)array, count, (int (*)(void *, void *)SortCompare<T>);
    }

    and for every array of type T you need to sort, define a int SortCompare&ltT&gt(T *arg1, T *arg2). (You could, alternately still pass that function to the generic sort routine, if you had different comparison functions for the same types of data (say, case-sensitive and case-insensitive sorting, or lexicographic vs. ASCII text sorting, etc.).)

    Note the inline declaration. This lets a smart compiler code the call to the generic function inline, avoiding a double function call. In practice, if the only thing you are doing is some type casting, no additional code is generated.

    So, you still have the potentially dangerous downcasting, but you've encapsulated it inside a template definition, relieving the application programmer to have to worry about it. Does all this mean extra work? It sure looks that you have to come up with a generic implementation and then make a nice and pretty templated type-safe wrapper around it.

    This is true, and well worth the effort for code that has to be robust and easy to use, particularly by others. Library writers know this rule all too well.

    Of course, in a pinch, or when a generic implementation is not obvious, or known to be non-existent, or when a particulary implementation exists for some types of objects, you can punt and let the compiler generate multiple instances of type-safe code, without a generic back-end implementation, accepting the code bloat that results.

    In the end, it becomes a matter of compromise and wise design decisions. Unfortunately, with choice, comes the effort to chose, and to chose wisely. It is the unwise use of templates that leads to their sometimes ill-deserved "code bloat" reputation. One of the differences between the skilled and less-skilled programmer is the ability to make these choices correctly and quickly, leveraging the language features that let the corresponding design decisions be put into practice.

    Other related C++ topics would include the notions that "multiple inheritence leads to slow code," "exception handling and run-time type information have high overhead". Again, one has to weigh the advantages offered by these techinques against the skill needed to use them wisely, and the performance penalty paid. I'll let someone else chime in now.

    --
    You could've hired me.