This month, a new book from one of the foremost C++ experts Scott Meyers became available: Effective Modern C++, subtitled 42 Specific Ways to Improve Your Use of C++11 and C++14. The present post gives my humble review of this jewel.
- Author: Scott Meyers
- Title: Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14
- Publisher: O’Reilly Media
- Release Date: November 2014
- Pages: 336
More information can be found on the publisher’s website. The book is the last one of the author’s Effective software development series (Effective STL, Effective C++, More Effective C++).
Since the ratification of the C++11 and C++14 standards, many C++ textbooks have been revising their content to incorporate the changes these standards brought. However, textbooks usually include just a description of the features the C++ standards provide. Programmers are then left alone in the wild to figure out how to use these features in real-world code. Moreover, when using language features, it is desirable to use them effectively. That is, use them so that the code is correct, efficient, maintainable, and portable. As the book’s title suggests, it is precisely about this: how to use C++11 and C++14 effectively.
The book is aimed at intermediate and expert-level C++ programmers who already know the basics of C++11/14 and want to improve their use. If you are used to C++98 but completely new to C++11, you should spend some time learning about the new features before reading this book. Indeed, the book is about the use of C++11/14. If you have never played chess, you will gain more from an introductory textbook rather than from a book on chess strategy. Moreover, as the book makes many references to C++98 (the previous C++ standard), you can see how the language evolved and what new it offers. That is, of course, if you know C++98. However, I would say that most today’s C++ programmers do, even if the level of knowledge differs.
As the book’s table of contents reveals, it concentrates its main attention to the following topics:
- Type deduction rules,
decltype, and the importance of understanding them.
- Moving to modern C++. What C++11/14 features should we prefer over the ones provided by C++98 and why.
- Smart pointers. Why should we prefer their use over raw pointers.
- Rvalue references, move semantics, and perfect forwarding. Understanding them, their strengths and failure cases.
- Lambda functions.
- The concurrency API. Threads, futures, and atomicity.
The book is very well written. I like the way the author highlights the important parts of code samples from the not-so-much important ones. In this way, you do not have to stare at the code, wondering about what changed. Every code sample is crystal clear. The author tried really hard to make the text and code samples as readable and understandable as possible. By providing detailed explanations, easy-to-follow code samples, and logical reasoning, I often found myself having “aha” moments: realizing precisely why something works the way it does and why something else does not work as expected. The author compellingly convinces the reader that to master C++ and use it effectively, you need to truly understand its underlying principles.
It is good that the book presents not only the strengths of C++11/14 constructs, but also their weaknesses and failure cases. As with other areas of software development, the use of many C++ constructs is about compromise. Sometimes, they may do what you want, but other times, alternatives may be better. Therefore, a lot of the advices the book gives is of the form prefer X to Y, not always use X. The great thing is that after reading the book, you will be able to decide which way to choose based on solid reasons and arguments.
Another good thing about the book is that it shows how the language features work together. Even though the book is divided into chapters by the topic they cover, there are many cross references. This way, if you do not understand something in a code snippet, there is a reference to the section where the feature is covered. More importantly, you can see how the language features fit together, like pieces of a jigsaw puzzle.
The book is about C++11 and C++14. However, as the approval of the C++14 standard happened only a few months ago, it is quite possible that your environment (e.g. the used compiler) does not allow you to utilize all the features C++14 provides. Fear not, though. The book clearly separates what can be done in C++11 from what can be written by using C++14. For C++14 constructs that are missing in C++11, it often gives ways to emulate them.
To summarize, if you aim to be a professional C++ developer, this book is a must-have. It provides the most up-to-date coverage of the effective use of C++11 and C++14 I have read. Moreover, this book is not to be read just once and then tossed away. Indeed, I am looking forward to read it again because it contains so much wisdom.