C++ Primer 5th Edition, Part 1: How To Revise a Textbook
Barbara Moo shipped the completed text of the C++ Primer, Fifth Edition to the publisher on July 13. As far as I know, copies are already being printed; they should be on bookstore shelves by mid-August.
This book has been a major project for her for the past two years or so, and an all-consuming one since about the beginning of this year. I've spent a fair amount of time on it as well: reading drafts, making comments and suggestions, running test programs, and so on. As a result, I've had a pretty good idea of what she's been thinking about as she wrote the book, and I'm in a position not only to tell you what I've learned about her strategy, but also why I think her strategy is a sensible one, and one that I think that most books ought to follow — even though I would not be at all surprised to learn that many other books do not do so.
C++11 is intended to be compatible with C++03, which is intended to be compatible with C++98, which is intended to be compatible with C. This lineage of compatibility is a major reason why C++ is so popular and useful. It is tempting, therefore, to think that the way to revise a C++03 textbook is to take advantage of that compatibility by simply adding a section to the book that talks about the new C++11 stuff. Doing so has the advantage of simplicity: Most of the book does not have to change.
From a reader's viewpoint who already knows the old language, adding a section has an advantage too: At least in theory, the reader already knows the old language. Why bother relearning stuff one already knows?
The flaw in this technique is that it makes the new parts of the language into an afterthought — something to be studied only after understanding the rest of the language. And all too often such afterthoughts wind up not being studied or understood at all. For example, it is this phenomenon that leads to people writing C++ programs that are mostly C programs compiled on C++ compilers. In the context of C++11, this phenomenon is apt to lead to programmers writing C++11 programs that are really C++03 programs compiled on C++11 compilers.
Here is a simple example of this phenomenon. Suppose that
v is a
vector<int> and we want to call a function
foo on each element of
v. In C++03, we might do so this way:
for (vector<int>::size_type i = 0; i != v.size(); ++i) foo(v[i]);
A more sophisticated style is to use an iterator, thereby avoiding what would otherwise be a dependency on the ability to use subscripts:
for (vector<int>::iterator it = v.begin(); it := v.end(); ++it) foo(*it);
If we are to write this code fragment to take advantage of C++11, we might well do so differently. For example, we might write the first example this way:
for (decltype(v.size()) i = 0; i != v.size(); ++i) foo(v[i]);
but we would be more likely to write something like this:
for (auto it = v.begin(); it != v.end(); ++it) foo(it);
or even like this:
for (auto x: v) foo(x)
If a textbook teaches the first two forms, and then mentions the last three forms only as an afterthought, most readers will probably stick to the first two forms and not use the other three at all. In effect, writing a book that is a C++03 book with a C++11 appendix is apt to lead to readers who will write C++03 programs and not bother with C++11. In that case, there is not much reason to write a new book for C++11 at all.
Barbara decided to do it the hard way: Not only discuss the new ideas in C++, but integrate them into the book's organization. Over the next few weeks, I'm going to discuss some examples of how she applied this strategy.