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

стр.

Вот как наша функция >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. Тип переменных, объявленных как