Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - [19]

Шрифт
Интервал

Применение >auto гарантирует, что вам не придется этим заниматься:

>auto sz = v.size(); // Тип sz – std::vector::size_type

Все еще не уверены в разумности применения >auto? Тогда рассмотрите следующий код.

>std::unordered_map m;

>…

>for (const std::pair& p: m) {

> … // Что-то делаем с p

>}

Выглядит вполне разумно… но есть одна проблема. Вы ее не видите?

Чтобы разобраться, что здесь не так, надо вспомнить, что часть >std::unordered_map, содержащая ключ, является константной, так что тип >std::pair в хеш-таблице (которой является >std::unordered_map) вовсе не >std::pair, а >std::pair. Но переменная >p в приведенном выше цикле объявлена иначе. В результате компилятор будет искать способ преобразовать объекты >std::pair (хранящиеся в хеш-таблице) в объекты >std::pair (объявленный тип >p). Этот способ — создание временного объекта типа, требуемого >p, чтобы скопировать в него каждом объект из >m с последующим связыванием ссылки >p с этим временным объектом. В конце каждой итерации цикла временный объект уничтожается. Если этот цикл написан вами, вы, вероятно, будете удивлены его поведением, поскольку почти наверняка планировали просто связывать ссылку >p с каждым элементом в >m.

Такое непреднамеренное несоответствие легко лечится с помощью >auto:

>for (const auto& p : m) {

> … // Как и ранее

>}

Это не просто более эффективно — это еще и менее многословно. Кроме того, этот код имеет очень привлекательную особенность — если вы возьмете адрес >p, то можете быть уверены, что получите указатель на элемент в >m. В коде, не использующем >auto, вы получите указатель на временный объект — объект, который будет уничтожен в конце итерации цикла.

Два последних примера — запись >unsigned там, где вы должны были написать >std::vector::size_type, и запись >std::pair там, где вы должны были написать >std::pair, — демонстрируют, как явное указание типов может привести к неявному их преобразованию, которое вы не хотели и не ждали. Если вы используете в качестве типа целевой переменной >auto, вам не надо беспокоиться о несоответствиях между типом объявленной переменной и типом инициализирующего ее выражения.

Таким образом, имеется несколько причин для предпочтительного применения >auto по сравнению с явным объявлением типа. Но >auto не является совершенным. Тип для каждой переменной, объявленной как >auto, выводится из инициализирующего ее выражения, а некоторые инициализирующие выражения имеют типы, которые не предполагались и нежелательны. Условия, при которых возникают такие ситуации, и что при этом можно сделать, рассматриваются в разделах 1.2 и 2.2, поэтому здесь я не буду их рассматривать. Вместо этого я уделю внимание другому вопросу, который может вас волновать при использовании >auto вместо традиционного объявления типа, — удобочитаемость полученного исходного текста.

Для начала сделайте глубокий вдох и расслабьтесь. Применение >auto — возможность, а не требование. Если, в соответствии с вашими профессиональными представлениями, ваш код будет понятнее или легче сопровождаемым или лучше в каком-то ином отношении при использовании явных объявлений типов, вы можете продолжать их использовать. Но имейте в виду, что С++ — не первый язык, принявший на вооружение то, что в мире языков программирования известно как вывод типов (type inference). Другие процедурные статически типизированные языки программирования (например, С#, D, Scala, Visual Basic) обладают более или менее эквивалентными возможностями, не говоря уже о множестве статически типизированных функциональных языков (например, ML, Haskell, OCaml, F# и др.). В частности, это объясняется успехом динамически типизированных языков программирования, таких как Perl, Python и Ruby, в которых явная типизация переменных — большая редкость. Сообщество разработчиков программного обеспечения имеет обширный опыт работы с выводом типов, и он продемонстрировал, что в такой технологии нет ничего мешающего созданию и поддержке крупных приложений промышленного уровня.

Некоторых разработчиков беспокоит тот факт, что применение >auto исключает возможность определения типа при беглом взгляде на исходный текст. Однако возможности IDE показывать типы объектов часто устраняют эту проблему (даже если принять во внимание обсуждавшиеся в разделе 1.4 вопросы, связанные с выводом типов в IDE), а во многих случаях абстрактный взгляд на тип объекта столь же полезен, как и точный тип. Зачастую достаточно, например, знать, что объект является контейнером, счетчиком или интеллектуальным указателем, не зная при этом точно, каким именно контейнером, счетчиком или указателем. При правильном подборе имен переменных такая абстрактная информация о типе почти всегда оказывается под рукой.

Суть дела заключается в том, что явно указываемые типы зачастую мало что дают, кроме того что открывают возможности ошибок — в плане как корректности, так и производительности программ. Кроме того, типы >auto автоматически изменяются при изменении типов инициализирующих их выражений, а это означает облегчение выполнения рефакторинга при использовании


Еще от автора Скотт Мейерс
Эффективное использование STL

В этой книге известный автор Скотт Мейерс раскрывает секреты настоящих мастеров, позволяющие добиться максимальной эффективности при работе с библиотекой STL.Во многих книгах описываются возможности STL, но только в этой рассказано о том, как работать с этой библиотекой. Каждый из 50 советов книги подкреплен анализом и убедительными примерами, поэтому читатель не только узнает, как решать ту или иную задачу, но и когда следует выбирать то или иное решение — и почему именно такое.


Как функции, не являющиеся методами, улучшают инкапсуляцию

Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Платформа J2Me

Эта книга научит вас, как разрабатывать программное обеспечение для платформы J2ME компании «Sun Microsystems». Эта книга придерживается стиля учебного пособия, это не справочное руководство.Цель — дать вам твердую основу в понятиях и техниках, которая даст вам возможность решиться на самостоятельную разработку качественных приложений.


Виртуальная библиотека Delphi

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка баз данных на Visual Basic.NET

Это практическое руководство разработчика программного обеспечения на Visual Basic .NET и ADO.NET, предназначенное для создания приложений баз данных на основе WinForms, Web-форм и Web-служб. В книге описываются практические способы решения задач доступа к данным, с которыми сталкиваются разработчики на Visual Basic .NET в своей повседневной деятельности. Книга начинается с основных сведений о создании баз данных, использовании языка структурированных запросов SQL и системы управления базами данных Microsoft SQL Server 2000.


Исчерпывающее руководство по написанию всплывающих подсказок

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Программное обеспечение встроенных систем. Общие требования к разработке и документированию

Embedded system software. General requirements for development and documentationСтандарт подготовлен в развитие ГОСТ Р ИСО/МЭК 12207-99 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.