Обзор книги Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14

Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14

Книга была выпущена под занавес 2014 года, аккурат после принятия нового стандарта C++. Она написана Скоттом Майерсом(Scott Meyers) — автором, которого любой уважающий себя программист C++ должен знать в лицо. Три его предыдущие книги встречаются в любом списке литературы, рекомендуемой к прочтению по C++. Конечно, его книги не предназначены для новичков, а, скорее, являются неким вариантом продолжения изучения тонкостей C++, за пределами учебников по языку. Книги Скотта Майерса это некий экстракт опыта многих программистов, который он переводит в текст и представляет на суд читателя. До сих пор он не давал промашек — его книги были великолепны.

Ну да то дело прошлое, а у нас на повестке дня новая книга. Что хочется сказать сразу — прогресс не стоит на месте, и по качеству исполнения новая книга оставляет позади старые. Безусловно, это скорее похвала «Орейли», чем автору. Тем не менее, используется более качественная бумага, в тексте больше цвета, и вообще книга выполнена гораздо приятнее любой из 3-х предыдущих.

Что касается языка написания, то он, как и ожидалось, не изменился. Такой же живой, с некоторым юмором, подход к объяснению не самых простых вещей сохранился и продолжает радовать читателя.

Как и предыдущие книги, настоящий труд разделён на пункты(items), где каждый пункт является неким советом как эффективнее использовать ту или иную функциональность нового стандарта. Майерс не пошёл настолько далеко, чтобы провести ревизию советов из предыдущих книг, а просто представил новые советы, которые основаны на нововведениях в C++11 и C++14. В книге он указывает, в каком именно стандарте появилась та или иная функциональность — это очень удобно для тех, кто по каким-то причинам ещё не может насладиться полноценным использованием C++14.

Первые две части книги посвящены темам связанным  с auto и decltype. Майерс подробно объясняет правила выведения шаблонного параметра, при инстанциации, а также как это всё связано с auto, decltype и decltype(auto). Этот материал написан очень качественно и может использоваться как справочный, когда хочется освежить в памяти ��се эти правила, а стандарт читать нет желания. После этого идёт часть, посвящённая всяким разным новым штукам: constexpr, nullptr, enum class и т.д. Тут Майерс пробегает «галопом по Европам», поясняя где вы можете получить выгоду от использования новых возможностей.

Следующая большая часть посвящена «умным указателям», которая поясняет где и когда стоит использовать тот или иной указатель. Не умаляя других интересных вещей, которые автор описывает в этой части, из этой части я вынес ранее не известный мне факт — std::shared_ptr содержи конструктор, который принимает std::unique_ptr. Это коренным образом меняет способ написания функций-фабрик. Как я это мог упустить, когда следил за развитием C++11 — ума не приложу.

После «умных указателей», автор переходит к довольно интересной и, наверное, наименее понятной программистам теме из нового стандарта — семантике перемещения. Здесь вы узнаете о том, когда и зачем стоит использовать std::move и std::forward, а также о том, как же работают т.н. «универсальные ссылки»(этот термин, кстати, придумал Майерс, но он не является общепринятым). Обо всём этом я тоже писал, так что может быть будет полезным прочитать оба материала.

Далее идёт часть посвящённая использованию лямбда-выражений и тут я наткнулся на один пункт(item) с которым я просто совершенно не согласен. Этот пункт имеет номер 31. Я не собираюсь здесь вступать в спор с автором и навязывать своё мнение, но на мой взгляд, данный пункт не имеет право на существование. В остальном часть тоже вполне неплохо написана.

Предпоследняя часть посвящена конкурентному API, которое появилось в C++11. В целом часть написана неплохо, но лучше почитайте C++ Concurrency in Action: Practical Multithreading, из неё вы узнаете куда больше. Ну а если уже читали, тогда эта часть вам попросту ни к чему. Она довольно поверхностно написана.

Два последних пункта вынесены в отдельную часть, по принципу «больше некуда было воткнуть». Тем не менее они весьма интересны, один посвящён вопросу: «быть или не быть передаче по значению», а второй касается нового интерфейса вставки элементов в базовые контейнеры.

Что хочется сказать о книге в целом: она получилась, она ничем не хуже своих предшественниц, и её также стоит рекомендовать к прочтению всем C++-программистам. Книга получает жирную 5-ку и почётное место на полке.