Книга ужасов "Effective Modern С++"
Scott Meyers "Effective Modern С++" (2016), в русском варианте Скотт Мейерс "Эффективный и современный С++". В процессе чтения обоих изданий: в дороге - epub с оригиналом на электрокнижке, на компьютере - PDF с переводом. Сюда буду кидать заметки по ходу.
Многостраничное предисловие, рассказывающее о том, как автор потел от усилий на спецфорумах, в конференциях usenet и на stackoverflow, чтобы понять "как эта хрень действительно работает", наводит на прямые аналогии с печальной историей эволюции языка PL/1. Си++ -- язык со сложной судьбой, непревзойденный чемпион по способам выстрелить себе в ногу, поэтому увеличить его страдания навешиванием новых фишек легко. И, похоже, основываясь на многочисленных "хотелках" и "интертрепациях" задач сообщества, дело пошло резво.
25 страниц посвящено описанию нового способа эффективно отстрелить себе пальцы -- использованию auto
и выводу типов для auto
и шаблонов. Двадцать пять, Карл! Зачем была вообще введена эта возможность? Оказывается, для облегчения переносимости типов и избавления от typedef
. На протяжении многих страниц автор пытается сформулировать правила, по которым программист может попытаться угадать, какой же в действительности тип выведет компилятор.
Попутно автор сам того не желая пинает другое новшество -- инициализацию в фигурных скобочках.
auto x1 = 27; // Тип int, значение 27
auto x2(27); // То же самое
auto x3 = {27}; // Тип std::initializer_list<int>, значение { 27 }
auto x4{27}; // То же самое
// при этом
int x5{27}; // Тип int, значение 27
int x6 = {27}; // То же самое
Как правильно отмечено в книге, "эта ловушка является одной из причин, по которым некоторые разработчики используют фигурные скобки в инициализаторах только тогда, когда обязаны это делать". Иными словами, вменяемые программисты понимают, что новый синтаксис инициализации переменных -- очередной способ обделаться на ровном месте, поэтому не надо им пользоваться.
Синтез всего двух фишек, типа auto
и инициализации, приводит к таким потрясающим эффектам! Очевидно, активисты, проталкивавшие в стандарт первую, не думали о второй и наоборот. При отсутствии архитектора, ушедшего читать лекции по Си++ первокурсникам техасского универа, получается как-то неудобно, да.
Не совсем понятно желание стандартизаторов превратить Си++ в этакий компилируемый в родной код недо-Питон. Потому что для соответствующих задач нормальный программист просто возьмет Питон. С другой стороны, высокая популярность языка Си (без плюсов) говорит о том, что многие перестали видеть в новшествах смысл и предпочтут писать контролируемый софт на более простом и ясном языке даже поступившись объемом исходников и уровнем абстракций.
Следующая глава была посвящена вопросам сочетания инициализации фигурными скобочками с конструкторами, использующими initializer_list
. Очередной способ прострелить себе ногу требует не только аккуратности, но и отслеживания изменений и расширений старого кода. В самом деле, если раньше у класса был, например, конструктор, принимающий два целых числа, то он использовался как в каноническом варианте со скобками, так и с фигурными.
class MyClass
{
public:
MyClass() {}
MyClass(int a, int b) {}
};
...
MyClass a(1, 2); // вызывает MyClass(int a, int b)
MyClass a{1, 2}; // то же самое
Но вот коллега Вася решил дописать классу конструктор с переменным числом целочисленных параметров (да, васины действия противоречат принципу проектирования "open-close", но и при наследовании проблема останется). И ба-бах! Старый код, где по каким-то причинам использовалась инициализация в фигурных скобках, перестал вызывать конструктор с двумя параметрами. Легким движением руки Вася захватил контроль.
class MyClass
{
public:
MyClass() {}
MyClass(int a, int b) {}
MyClass(std::initializer_list<int> params) {}
};
...
MyClass a(1, 2); // вызывает MyClass(int a, int b)
MyClass a{1, 2}; // теперь вызывает MyClass(std::initializer_list
Мне даже пришлось написать более подробный тест-пример для уяснения тонкостей вызова конструкторов. Наверное, это тоже интересное занятие, если проект новый или другой работы нет.
Продолжение следует...
blog comments powered by Disqus