Главная » Просмотр файлов » С. Мейерс - Эффективный и современный C++

С. Мейерс - Эффективный и современный C++ (1114942), страница 9

Файл №1114942 С. Мейерс - Эффективный и современный C++ (С. Мейерс - Эффективный и современный C++) 9 страницаС. Мейерс - Эффективный и современный C++ (1114942) страница 92019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 9)

Если компилятор не в со­стоянии получить достаточно информации о вашем коде, чтобы выполнить вывод типа,вы не сможете увидеть выведенные типы.Для простых типов наподобие int информация из IDE в общем случае вполне точна.Однако, как вы вскоре увидите, когда приходится иметь дело с более сложными типами,информация, выводимая IDE, может оказаться не особенно полезной.Диаrностика комп илятораЭффективный способ заставить компилятор показать выведенный тип - использо­вать данный тип так, чтобы это привело к проблемам компиляции.

Сообщение об ошиб­ке практически обязательно будет содержать тип, который к ней привел.Предположим, например, что мы хотели бы узнать типы, выведенные для х и у изпредыдущего примера. Сначала мы объявляем шаблон класса, но не определяем его. Чего­то такого вполне хватит:42Глава 1 . Вывод типовtemplate<typename Т>class TD;/! Только объявление TD;Попытки инстанцировать этот шаблон приведут к сообщению об ошибке, поскольку ин­станцируемый шаблон отсутствует. Чтобы увидеть типы х и у, просто попробуйте ин­станцировать TD с их типами:TD<decltype ( x ) > хТуре ; / / Сообщение об ошибке будетTD<decltype ( y ) > уТуре ; / / содержать типы х и уЯ использую имена переменных вида variaЫeNameType, чтобы проще найти интере­сующую меня информацию в сообщении об ошибке. Мой компилятор для приведенноговыше кода сообщает, в частности, следующее (я выделил интересующую меня информа­цию о типах):error: aggregate ' TD<int> хТуре ' has incomplete type andcannot Ье def inederror: aggregate ' TD<const int *> уТуре ' has incomplete typeand cannot Ье definedДругой компилятор выдает ту же информацию, но в несколько ином виде:error: ' хТуре ' uses undefined class ' TD<int> 'error : ' уТуре ' uses unde fined class ' TD<const int * > 'Если н е учитывать разницу в оформлении, все протестированные мною компиляторыпри использовании этого метода генерировали сообщения об ошибках с интересующейменя информацией о типах.В ывод времени вып оп ненияПодход с использованием функции вывода для отображения сведений о типе можетбыть использован только во время выполнения программы, зато он предоставляет пол­ный контроль над форматированием вывода.

Вопрос в том, чтобы создать подходящеедля вывода текстовое представление информации. "Без проблем, - скажете вы. - Намна помощь придут t yp e i d и s t d : : type_i nfo : : name': В наших поисках информациио выведенных для х и у типах можно написать следующий код:std: : cout « typeid(x) . name ( ) « ' \n ' ; / / Выведенные типыstd : : cout << typeid(y) . name ( ) << ' \n ' ; / / для х и уЭтот подход основан на том факте, что вызов typ e id для такого объекта, как х или у,дает объект std : : type_info, а он имеет функцию-член name, которая дает С-строку (т.е.const char*), представляющую имя типа.Не гарантируется, что вызов std : : t ype_ i n fo : : name вернет что-то разумное, но егореализации изо всех сил пытаются быть полезными. Уровень этой полезности варьи­руется от компилятора к компилятору.

Компиляторы GNU и Clang, например, сообща­ют, что тип х - это "i'; а тип у"PKi". Эти результаты имеют смысл, если вы будетезнать, что "i" у данных компиляторов означает "int'; а "рк" - "указатель на константу':-1 . 4. Как просмотреть выведенные типы43(Оба компилятора поддерживают инструмент c+ + f i l t , который расшифровывает этиимена.) Компилятор Microsoft генерирует менее зашифрованный вывод: " int " для хи " int const * " для у.Поскольку это корректные результаты для типов х и у, вы можете подумать, что за­дача получения информации о типах решена, но не делайте скоропалительных выводов.Рассмотрим более сложный пример:template<typename Т>void f ( const Т& param) ;11 Шаблонная функция,/ / вызываемая далееstd : : vector<Widget> createVec ( ) ; / / Фабричная функцияconst autovwcreateVec ( ) ;=i f ( 1 vw empty ( ) )f ( &vw [O] ) ;/ / Инициализация vw возвратом11 фабричной функции./ / Вызов fЭтот код, включающий пользовательский тип (Wi dget ) , контейнер STL ( s t d : : vector )и переменную auto { vw) , является более представительным и интересным примером.Было бы неплохо узнать, какие типы выводятся для параметра типа шаблона Т и для па­раметра param функции f.Воспользоваться t ypeid в этой задаче достаточно просто.

Надо всего лишь добавитьнемного кода в функцию f для вывода интересующих нас типов:template<typename Т>void f ( const Т& param){us ing std : : cout ;11 Вывод в nоток cout типа Т :cout < < " Т< < typeid (T) . name ( ) < < ' \ n ' ;="1 1 Вывод в лоток cout типа param:<< typeid (param) . name ( ) << ' \ n ' ;cout << "param="Выполнимые файлы, полученные с помощью компиляторов GNU и Clang, дают сле­дующий результат:ТparamPKбWidgetPK6WidgetМы уже знаем, что в этих компиляторах РК означает указатель на константу, так что всязагадка - в цифре 6. Это просто количество символов в следующем за ней имени класса44Глава 1 .

Вывод типов(W idget ) . Таким образом, данные компиляторы сообщают нам, что и Т, и pa ram имеютодин и тот же тип - const Widge t * .Компилятор Microsoft согласен:Тparamclass Widget const *class Widget const *Три независимых компилятора дают одну и ту же информацию, что свидетельствуето том, что эта информация является точной. Но давайте посмотрим более внимательно.В шаблоне f объявленным типом param является тип const Т&. В таком случае не кажет­ся ли вам странным, что и Т, и param имеют один и тот же тип? Если тип Т, например,представляет собой int, то типом param должен быть const int &совершенно другойтип.К сожалению, результат s t d : : t ype_info : : name ненадежен.

Например, в данном слу­чае тип, который все три компилятора приписывают param, является неверным. Крометого, он по сути обязан быть неверным, так как спецификация std : : t ype_ info : : nameразрешает, чтобы тип рассматривался как если бы он был передан в шаблонную функ­цию по значению. Как поясняется в разделе 1 . 1 , это означает, что если тип являетсяссылкой, его "ссылочность" игнорируется, а если тип после удаления ссылочности ока­зывается const (или volat i l e ) , то соответствующие модификаторы также игнорируют­ся.

Вот почему информация о типе pa ram - который на самом деле представляет собойconst Widget * cons t&выводится как const Widget * . Сначала удаляется ссылочность,а затем у получившегося указателя удаляется константность.Не менее печально, что информация о типе, выводимая редакторами IDE, также не­надежна - или как минимум ненадежно полезна. Для этого же примера мой редакторIDE сообщает о типе т как (я не придумываю!):--conststd : : _Simple t ypes<std : : _Wrap_al loc<std : : _Vec_base_types<Widge t ,std : : al locator<W1dget> > : :_Alloc> : : value type> : : value_type *Тот же редактор IDE показывает, что тип param следующий:const std : : Simple_types< . . . > : : value_type *const &Это выглядит менее страшно, чем тип Т, но троеточие в средине типа сбивает с толку,пока вы не поймете, что это редактор IDE попытался сказать "Я опускаю все, что являет­ся частью типа т': Ваша среда разработки, быть может, работает лучше моей - если выдостаточно везучий.Если вы склонны полагаться на библиотеки больше, чем на удачу, то будете радыузнать, что там, где std : : t уре_ i n fo : : name и IDE могут ошибаться, библиотека BoostTypelndex (часто именуемая как Boost.

Typelndex) приведет к успеху. Эта библиотека неявляется частью стандарта С++, но точно так же частью стандарта не являются ни IDE,ни шаблоны наподобие рассмотренного выше T D. Кроме того, тот факт, что библиоте­ки Boost (доступные по адресу boost . org } являются кроссплатформенными, с откры­тым исходным кодом и с лицензией, разработанной так, чтобы быть приемлемой даже1 .4 . Как просмотреть выведенные типы45для самых параноидальных юристов, означает, что код с применением библиотек Boostпереносим практически так же хорошо, как и код, основанный на стандартной биб­лиотеке.Вот как наша функция f может выдать точную информацию о типах с использовани­ем Boost.Typelndex:#include <1:юost/ type_index . hpp>template<typename Т>void f ( const Т& param){using std: : cout ;using Ьoos t : : typeindex : : type id with cvr ;_ __/ / Вывод информации о Тcout << "Т ; "<< type_id_with_cvr<T> ( ) .

pretty_name ( )<< , \n , ;1 1 Вывод информации о типе paramcout << "param ; "<< type_id_with_cvr<decltype ( param ) > ( ) . pretty пame ( )_<< ' \n ' ;Как это работает? Шаблон функции boos t : : t yp e i ndex : : t yp e id w i t h cvr получаетаргумент типа (тип, о котором мы хотим получить информацию) и не удаляет const,vola t i l e или квалификатор ссылки (о чем и говорит "w i t h_cvr" в имени шаблона). Ре­зультатом является объект boo s t : : t yp e index : : t ype_ i ndex, функция-член pretty_nameкоторого дает s t d : : s t r i ng с удобочитаемым представлением типа.При такой реализации f обратимся вновь к вызову, который давал нам неверную ин­формацию о типе param при использовании t ype id:---std : : vector<Widget> createVec ( ) ; / / Фабричная функцияconst auto vw ; createVec ( ) ;i f ( ! vw . empty ( ) )f ( &vw [ O ) ) ;/ / Инициализация vw с помощью11 фабричной функции11Вызов fПосле компиляции с помощью компиляторов GNU и Clang Boost.Typelndex дает следую­щий (точный) результат:Т; Widget const *param ; Widget const * const &46Гnава 1 .

Вывод тмповПрименение компилятора Microsoft дает по сути то же самое:Тpararnclass Widget const *class Widget const * const &Такое единообразие - это хорошо, но важно помнить, что редакторы IDE, сообще­ния об ошибках компилятора и библиотеки наподобие Boost.Typelпdex являются всеголишь инструментами, которые можно использовать для выяснения того, какие типы вы­водит ваш компилятор. Это может быть полезно, но не может заменить понимания ин­формации о выводе типов, приведенной в разделах 1 .

Характеристики

Тип файла
PDF-файл
Размер
12,67 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6310
Авторов
на СтудИзбе
312
Средний доход
с одного платного файла
Обучение Подробнее