Review of Modern C++ Design

Home Blog Talks Books & Articles Training & Consulting

Prev
Up
Next

On the
blog
RSS feed November 4: Other Concurrency Sessions at PDC
November 3
: PDC'09: Tutorial & Panel
October 26: Hoare on Testing
October 23
: Deprecating export Considered for ISO C++0x

Review of Modern C++ Design

This article appeared in C/C++ Users Journal, 20(4), April 2002.

 

Anyone who thinks they’ve seen it all in C++, or that there’s nothing new left to be said, obviously hasn’t read Modern C++ Design.

Modern C++ Design is an important book. Fundamentally, it demonstrates how to create reusable design pattern implementations in C++—a new way to combine templates and patterns that you may never have dreamt was possible, but is.

Modern C++ Design is not for novices. There are a lot of advanced techniques here, but it’s a testament to Alexandrescu’s skill that he teaches advanced and useful design techniques in a way that’s easy to understand, assimilate, and put into practice on your next project. Better still, you can reuse the code in the book’s Loki library to solve real-world problems right away—with a few caveats that are due, not to Loki itself, but just to limitations in some of today’s compilers.

The Book

If your work involves production C++ design and coding, you should read this book. Even if you only read the first two chapters, you will come away with important ideas about how to design for extensibility in C++ and many useful supporting techniques based mainly on templates. But fair warning: If you do read the first two chapters, you’ll probably be hooked and won’t be able to stop until you reach the back cover. That’s a good thing, because although the first couple of chapters are cool and interesting, the real meat and value of the book comes later on.

We’ve probably all written Singleton and Visitor in our code. What’s more, the ugly truth is that we’ve all done it many times. This is because, as the patterns community is quick to remind us, design patterns are not code. Patterns, they are equally quick to elaborate, merely document recurring styles and idioms that crop up in the design process, and which then only later eventually manifest as code. The pattern description tells you what the pattern looks like, but then it’s up to you to go write new code every time you want to apply it.

Wouldn’t it be nice if, instead, patterns could be made available as reusable chunks of code you could call directly from your program, like std::list or std::sort() are? Aren’t you tired yet of writing Singleton and Visitor over and over? (If not, why not?) And so the main value and meat of Modern C++ Design lies in its techniques for creating just that: reusable implementations of design patterns, actual nuts-and-bolts code libraries than can be reused directly without hand-implementing them every time. Such “generic patterns” or “pattern templates,” as I think of them, are a powerful new way of creating extensible designs in C++. To demonstrate, Alexandrescu provides walkthroughs for several specific generic pattern implementations, devoting one chapter each to Abstract Factory, Multimethod, Smart Pointer, Singleton, and Visitor.

“But wait,” I can hear someone object, “that’s not how it works in practice! In the real world, there’s no one Singleton, there’s no one Visitor. We implement those patterns in different ways in different places even in the same program, depending on the exact requirements in each place they’re needed! I just don’t believe that there can be any useful one-size-fits-all solution.” (For example, consider the classic and thorny question of when a Singleton should be destroyed; the answer may be different for different Singletons in your program.)
That objection is perfectly valid, and I can imagine Alexandrescu smiling and rubbing his hands gleefully and responding: “Yup. And I’m glad you raised that question, because I was just getting to that part…” Such variability, as it turns out, is no barrier to Alexandrescu’s approach: he simply writes all (well, all right then, many) of the versions of Singleton you’ll ever need. You then instantiate the reusable Singleton implementation with policies that make it work the way you need in that particular place in your code, and instantiate it with different policies in other places. What if none of the default policies does quite what you want? Chances are you can write or specialize your own policy that will, thus writing the minimum code once, and only once, to extend and customize just that part of the pattern implementation’s behavior to account for the new requirement. The point is that the implementation of Singleton really is done once up front and then reused many times, instead of being implemented by hand in every place. No fuss, no muss.

Indeed, let me put it more succinctly still: Implementation variability is not a barrier to Alexandrescu’s approach; it’s the very reason his approach is important.

Oh, and he does the same with smart pointers. And Visitor. And Multimethods. Natty stuff.

An obligatory but minor caveat: The first printing of Modern C++ Design unfortunately contained numerous (literally hundreds of) typographical errors. I hasten to stress that these are not the author’s fault, but simply unfortunate production problems, and the typos are mostly obvious and don’t affect the quality of the material in the book. I also hasten to stress that this is probably of historical interest only, because by the time you read this review, you’ll almost certainly be buying the second or later printing, which pretty much have fixed these errors wholesale.

The Loki Library

Modern C++ Design describes the techniques and facilities available as the Loki library, which is freely available and downloadable and pretty much ready to use. If you want to try out some or all of Loki’s facilities, including Singleton and Visitor and others, you can do it today.

One of the things I’ve noticed that makes Loki so interesting is that “can compiler XYZ compile Loki?” is becoming something of an unofficial benchmark in compiler-writer circles. Don’t get me wrong, Loki is written entirely in normal standard-conforming C++—only more standard and more conforming, it turns out, than some compilers are yet quite ready to digest. Loki is one of the most technically advanced C++ libraries available, which is a polite way of saying that it uses templates so widely and heavily that it tears the tar and stresses the stuffing out of some current compilers. In fact, at the time the book was released, no commercially available compiler could compile all of Loki correctly, despite notes to the contrary in the book’s Preface about compilers which could compile most of Loki. But progress is being made: Recently, Loki has been ported to the Gnu g++ platform, with only minor tweaks to work around miscellaneous spots of compiler indigestion.

It’s a bit ironic that Loki is deliberately named after the Norse god of wit and mischief. The name was designed to highlight the playful flexibility of the library. It has an unintentional second application: Loki wreaks more mischief with today’s compilers than does any other popular library.

Summary

Although this book is definitely not for novices, it’s hard to overestimate the impact of Andrei Alexandrescu’s Modern C++ Design. Indeed, if Jim Coplien hadn’t already written an influential book called Advanced C++ Programming Styles and Idioms, I’m sure that’s what the title for Alexandrescu’s book could easily—and correctly—have been. Highly recommended for the serious C++ practitioner.

Copyright © 2009 Herb Sutter