C++ Templates: The Complete Guide
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.
The only place I ever saw a good use for Templates is in the C++ Container Classes and that woudn't be necessary if all C++ objects were inherited from one object like Java's objects are.
Templates only seem to be a necessary evil in OO languages that don't ultimately inherit all objects from one object.
I know a lot of people who are required, for their job, to write both Java and C++ code. Are templates really applicable to those developers? In other words when you switch back and forth between the two frequently do you resort to the lowest common denominators of the language instead of using more "advanced" aspects?
My J-Developer friend was just telling me the other day how he longed for templates in Java.
--------
Free your mind.
"If you'd like to read some hairy code ... check out blitz++. :) And the errors you can get when compiling are simply astounding."
That is my biggest complaint with templates. Compilation errors can be horrendous, especially as they often appear far from point where you've made the error. My second biggest complaint are the debugger symbols that get produced for templates.
Microsoft just doesnt't compile them properly and it is very frustrating to all C++ programmers. Chances are, if you write C++ in the commercial world, your company has the very wise policy of making sure you stay roughly within the capabilities of the most popular compilers. This basically means you can use STL's vector, string, and list, and a pretty small collection of others. This, in my opinion, is a programmer's tragedy.
Utility C++ templates allow it to create and use some amazing things. I personally rarely write anything but the most simple ones, but when I'm allowed, there are huge libraries of amazing template classes. I learned ML at some point, and I remember the wonder when I happened upon the tuple template class for c++. With the exception of the fact you are forced to carry the type around (as a typedef of course), it works exactly like an ML tuple, a tool I came to love in my short time with ML. Someone simply wrote the template, and it was in C++ too! (a tuple is like an STL pair, but has an arbitrary number of members, set on construction).
Of course, even VC7 doesn't compile it. If you work at Microsoft in the Visual Studio area, PLEASE tell them to get standard compliant already! Yeah yeah templates can be slow to compile, but give us the option at least!
Your signatures belong to me.
Being fresh out of college, we used linked lists like they were going out of style. When I began work, I found out they were! Using an STL template and container serves as a good replacement for linked lists and other annoying data structures. I rarely use arrays anymore, I would rather use a vector or map. my personal preference, maybe because I hated linked lists and malloc arrays we exhaustively used in college.
100% Insightful
There is an interesting use for templates in 3D vector math:
http://www.flipcode.com/tutorials/tut_fastmath.sht ml.
It's a kludge, but it provides some real performance benefits.
They give the developer parametric polymorphism at design time, so she can deal with one "customizable" class instead of 20 slight modifications.
I gotta ask, when you think of a programmer, do you actually think of a girl programming? I mean good god, that 'she' thing as the neutral pronoun is more than a little phony isn't it? More women are graduating from colleges than men. They simply aren't choosing programming as a career in large numbers. Sorry, but it's a male-orientated profession. And I happen to know that you, as a human being, when you think of some generic programmer, think of a male. Probably a fat, coca-cola guzzling male.
Despite that mental image, your instinct for double-think kicks in. You choose the female pronoun for a host of social reasons.
And sorry, I don't like double-think, so I'm attacking you for it. Nobody talks like that in normal conversation. It's a middle-school English teacher grammar meme. A virus.
You cannot use C++ effectively and safely without templates.
The STL, especially, makes C++ an order of magnitude more usable and powerful.
Name one compiler that is 100% C++ standard compliant.
IMHO, is that a book like this needs to exist. Templates are *way* too complicated for something that is supposed to reduce complication.
I rarely see this in template discussions but the thing I love about templates is the ability to do template "closures" for lazy evaluation whereby instead of returning the result of a function, you return an object which represents the application of the function to those arguements. This object then gets cast into the final resultant object.
Why?
Lets say you are concatenating a bunch of strings. Normally, you would create the concatenation of two strings, then concatenate the third, etc. Depending upon your string implementation, you could reallocate the string results many times.
However, with template closures, the concatenation would return an object which pointed to the two objects that were to be concatenated. Then the second concatenation would point to that object plus the next string. When the entire object was finally actualized by, say, setting it to a variable or as a function argument, then it would create the final string. It could then gather the lengths of all the strings, create a single result string, and then copy everything into it.
And it wouldn't look any more complicated than:
string a = b + c + d + e;
or whatever and it would still be optimally efficient.
The big downside is that error messages are all but useless.
Synergies are basically awesome, and they're even better when you leverage them. -PA
However, it's nearly always fatal to mistake a tool (in this case, templates) for an end in itself (a functioning, maintainable codebase). No programming technology, be it HLL in general, objects, inheritance, or even templates will replace the need to think intelligently and make sound engineering decisions. You cannot build a skyscraper without the proper knowledge, no matter how excellent your hammer is.
The company I work for is among the few remaining who produce large-scale Windows products written entirely (ok, 99.9%) in C. My work is in a totally different world than the object oriented people, yet I still manage to accomplish everything an OO programmer could do. The secret here is not cute little language features, but discipline and correct design.
IMHO, templates do not deserve a book quite this large. Clearly, the author has had enormous experience in various situations, and knows how to solve all kinds of problems with templates, BUT -- remember the famous words passed down from people wiser than ourselves: "When all you have is a hammer, everything starts to look like a nail." Make sure the hammer isn't the only thing in your toolbox.
For those not too familiar with templates (personally I learned all from Stroustrup's book), there are a lot of interesting and sometimes quirky features.
One of the best examples perhaps is the STL vector class, which has three implementations. An implementation for a vector of booleans (made specifically to save space), a vector for any type of pointer, and then the generic vector class that covers anything else. Templates have some powerful features.
Unfortunately, there's still some things that need to be done in the compilers. Certain compilers in the past have had problems with them (hopefully they're fixed now), and errors in templated code are cryptically reported -- which always confused me. If compilers mangle a name to get the templates to compile, why can't they unmangle the name when reporting errors?
------------------
Lailyx -- Karma's overrated.
It is tempting to think of templates as just a fancy way to make a list of addresses (i.e. list) without having to do any casting. But templates let you do much, much more than that- It adds another tool to the programmers' arsenal by allowing him/her to decouple different parts of a program in order to improve its design. This new technique is called "Generic Programming" and C++ programmers like to think of it as being "orthogonal" to other ways of programming.
//y is now equal to 6
//i and iend are "iterators"
The first dimension of program design is to break code into procedures that can be called from several different places cleanly and transparently. This is what C and procedural programming made possible.
The second dimension is to have a type system that can channel the program to the correct code indirectly, either dynamically through OO polymorphism or statically through function overloading. This was what object-oriented programming and early C++ made possible.
The third orthogonal dimension is generic typing, or templating- Using this technique, new computer code can be created in a safe manner during compile time that allows abstractly-written pieces to be stuck together arbitrarily as needed to generate new code. All of these pieces have to fit perfectly in order for the compiler to accept it. If the pieces don't fit together perfectly, the programmer has many types of "glue" available (such as function adaptors, or iterator adaptors, etc.) to make them fit perfectly. If the glue isn't 100% perfect, the compiler lets you know and you can correct it. It can be a beautiful way to program if done correctly!
It also lets people program in a "functional" style, which was originally invented by LISP programmers, and is a great way to glue together abstract objects with abstract alorithms, without having many unsafe local variables. An example is "currying", where a function taking two parameters can be changed to require only one:
int multiply(int a,int b)//a function that multiplies two numbers
{
return a*b;
}
int(*x)(int)//x is a function that accepts only one number!
x=boost::bind(&multiply,2,_1);//set x equal to a newly created "version" of the multiply function that requires only one number- A function requiring 2 numbers now only requires one, without a local variable needed!
int y=x(3);
Another functional programming principle that is now possible is to write all your functions to use iterators, which are basically pointer-like objects that can point to anything: lists, arrays, stacks, almost anything! So to multiply all numbers together in an unknown(!) data structure you can write:
templatemultiply_all(T i,T iend)
{
T::value_type x;
while(i!=iend)
x*=i++;
return x;
}
If you begcome comfortable with thinking of all your data manipulation tasks in terms of iterators and use templates, a whole new world of programming techniques opens up to you!
If you want to be able to recognize what is the truth and what are lies (more lies) with Sun's J2EE and Microsoft .NET proprietary frameworks (however, they have and will have place in computing) study Standard C++ with the STL. Just reading Bjarne Stroustrup's interviews you will avoid shortsightedness and you will learn much more about computing then reading anything else.
Doing work near the hardware is no excuse not to use templates. On the contrary, I'd say that when you work on extremely performance critical code there is one thing you don't want your developers to do: reinventing the wheel over and over for non trivial parts of code - reinventing the wheel is something that's all too often done badly. A well written template will allow you to reuse well written, well tested efficient and small code over and over again for different types and different conditions without that risk.
Another reason to use templates in an embedded system is that it allow you to easily write reusable components that can be adapted to a particular situation at compile time instead of runtime, opening up reuse opportunities across projects that would otherwise be difficult. This is often done with traits classes or policy classes that allow you to turn on and off functionality of a template at compile time, leaving out any code that isn't actually used.
In fact, this is an important property of templates in C++: Code that isn't used isn't even semantically analysed, and certainly not included in the generated executable, while the same is not true for members of any class that is externally visible. So you might actually reduce your code size merely by changing some classes into templates even if they don't depend on any type parameter.
Oh, and I've worked on embedded systems, using exactly the above techniques, including one platform that had 4MB flash and 4MB RAM that we ran Linux on together with FTP and SNMP servers that I wrote (in C++) as well as various other application code, a shell, etc., so I am familiar with how to make C++ code small, and that is one of the reasons I love templates.
Later in the book, on template metaprogramming etc, there are lots of concrete examples. Perhaps the reviewer didn't read that far?
True, the book deals exclusively with C++. But contrary to what the reviewer states, it deals extensively with differences in C++ implementations. Whether or not one particular C++ compiler is listed in the index is not a very good judge!
Reading his last paragraph, I am sure now the reviewer did not read all of the book. It is not written in "cookbook" style, but for sure everyone reading the book will learn and discover new ideas for template design that they didn't know before. And the capabilities of parametric polymorphism are explored in detail, with quite large sections on how they could be extended (and possibly will, in the next C++ standard) to make some types of programming easier.
In short, this book is a mix between an academic treatise (it encapsulates practically all that is currently known about the C++ template mechanism), and practical guide to writing your own templates.