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

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

Вот как наша функция >f может выдать точную информацию о типах с использованием Boost.TypeIndex:

>#include


>template

>void f(const T& param) {

> using std::cout;

> using boost::typeindex::type_id_with_cvr;


> // Вывод информации о Т

> cout << "Т = "

>      << type_id_with_cvr().pretty_name()

>      << '\n';

> // Вывод информации о типе param

> cout << "param = "

>      << type_id_with_cvr().pretty_name()

>      << '\n';

>}

Как это работает? Шаблон функции >boost::typeindex::type_id_with_cvr получает аргумент типа (тип, о котором мы хотим получить информацию) и не удаляет >const, >volatile или квалификатор ссылки (о чем и говорит “>with_cvr” в имени шаблона). Результатом является объект >boost::typeindex::type_index, функция-член >pretty_name которого дает >std::string с удобочитаемым представлением типа.

При такой реализации >f обратимся вновь к вызову, который давал нам неверную информацию о типе >param при использовании >typeid:

>std::vector createVec(); // Фабричная функция


>const auto vw = createVec();     // Инициализация vw с помощью

>                                 // фабричной функции


>if (!vw.empty()) {

> f(&vw[0]);                      // Вызов f

>}

После компиляции с помощью компиляторов GNU и Clang Boost.TypeIndex дает следующий (точный) результат:

>Т = Widget const*

>param = Widget const* const&

Применение компилятора Microsoft дает по сути то же самое:

>Т = class Widget const *

>param = class Widget const * const &

Такое единообразие — это хорошо, но важно помнить, что редакторы IDE, сообщения об ошибках компилятора и библиотеки наподобие Boost.TypeIndex являются всего лишь инструментами, которые можно использовать для выяснения того, какие типы выводит ваш компилятор. Это может быть полезно, но не может заменить понимания информации о выводе типов, приведенной в разделах 1.1–1.3.

Следует запомнить

• Выводимые типы часто можно просмотреть с помощью редакторов IDE, сообщений об ошибках компиляции и с использованием библиотеки Boost.TypeIndex.

• Результаты, которые выдают некоторые инструменты, могут оказаться как неточными, так и бесполезными, так что понимание правил вывода типов в С++ является совершенно необходимым.

Глава 2

Объявление >auto

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

2.1. Предпочитайте >auto явному объявлению типа

Легко и радостно написать

>int x;

Стоп! #@$! Я забыл инициализировать >x, так что эта переменная имеет неопределенное значение. Может быть. Но она может быть инициализирована и нулем — в зависимости от контекста. Жуть!

Ну, ладно. Давайте лучше порадуемся объявлению локальной переменной, инициализированной разыменованием итератора:

>template // Некий алгоритм, работающий с

>void dwim(It b, It e) // элементами из диапазона от b до e

>{

> while (b != e) {

>  typename std::iterator_traits::value_type

>   currValue = *b;

> }

>}

Жуть. >typename std::iterator_traits::value_type — просто чтобы записать тип значения, на которое указывает итератор? Нет, я такой радости не переживу… #@$! Или я это уже говорил?..

Ладно, третья попытка. Попробую объявить локальную переменную, тип которой такой же, как у лямбда-выражения. Но его тип известен только компилятору. #@$! (Это становится привычкой…)

Да что же это такое — никакого удовольствия от программирования на С++! Так не должно быть. И не будет! Мы дождались С++11, в котором все эти проблемы решены с помощью ключевого слова >auto. Тип переменных, объявленных как >auto, выводится из их инициализатора, так что они обязаны быть инициализированными. Это значит — прощай проблема неинициализированных переменных:

>int x1;      // Потенциально неинициализированная переменная

>auto x2;     // Ошибка! Требуется инициализатор

>auto x3 = 0; // Все отлично, переменная x корректно определена

Нет проблем и с объявлением локальной переменной, значением которой является разыменование итератора:

>template // Все, как и ранее

>void dwim(It b, It e) {

> while (b != e) {

>  auto currValue = *b;

> }

>}

А поскольку >auto использует вывод типов (см. раздел 1.2), он может представлять типы, известные только компиляторам:

>auto derefUPLess =                     // Функция сравнения

> [](const std::unique_ptr& p1, // объектов Widget, на

>    const std::unique_ptr& p2) // которые указывают

>    { return *p1 < *p2; );             // std::unique_ptr

Просто круто! В С++14 все еще круче, потому что параметры лямбда-выражений также могут включать


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

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


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

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


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

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


Виртуальная библиотека 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 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.