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

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

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

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

Когда инициализатордля переменной, объявленной как a u t o , заключен в фигурные скобки, выведенныйтип - std : : ini t ial i zer_ 1 ist. Если такой тип не может быть выведен (например, из-затого, что значения в фигурных скобках относятся к разным типам), код будет отвергнут:auto х5 = { 1 , 2 , 3 . 0 } ; / / Ошибка ! Невозможно вывести Т// для std: : initializer_l ist<T>Как указано в комментарии, в этом случае вывод типа будет неудачным, но важ­но понимать, что на самом деле здесь имеют место два вывода типа. Один из них вы­текает из применения ключевого слова auto: тип х5 должен быть выведен.

Посколькуинициализатор х 5 находится в фигурных скобках, тип х 5 должен быть выведен какs t d : : i n i t i a l i z e r_l i s t . Но s t d : : i n i t i a l i z e r_l i s t - это шаблон. Конкретизацияпредставляет собой создание st d : : i n i t i a l i z e r_ l i s t <T> с некоторым типом Т, а этоозначает, что тип Т также должен быть выведен.

Такой вывод относится ко второй раз­новидности вывода типов - выводу типа шаблона. В данном примере этот второй выводнеудачен, поскольку значения в фигурных скобках не относятся к одному и тому же типу.Рассмотрение инициализаторов в фигурных скобках является единственным отличи­ем вывода типа auto от вывода типа шаблона. Когда объявленная с использованием клю­чевого слова auto переменная инициализируется с помощью инициализатора в фигурныхскобках, выведенный тип представляет собой конкретизацию s t d : : ini t i a l i z er_ l i s t .Но если тот же инициализатор передается шаблону, вывод типа оказывается неудачным,и код отвергается:auto х={ 11 , 23 , 9 } ; / / Тип х-std : : initializer list<int>templa te<typename Т>void f (Т param) ;// Объявление шаблона с параметром// эквивалентно объявлению хf ( { 11 , 23// Ошибка вывода типа для Т19 }) ;Однако, если вы укажете в шаблоне, что раrаm представляет собой std: : i ni t i a l i zer_ list<T>для некоторого неизвестного т, вывод типа шаблона сможет определить, чем является Т:template<typename Т>void f ( std: : initializer_list<T> initList ) ;34Глава 1 .

Вывод типовf ( { 11 , 23 , 9 } ) ; / / Вывод int в качестве типа Т, а тип1 1 initList - std : : ini tiali zer l i s t<int>Таким образом, единственное реальное различие между выводом типа auto и выводомтипа шаблона заключается в том, что auto предполагает, что инициализатор в фигурныхскобках представляет собой std : : ini t i a l i zer_l i st, в то время как вывод типа шаблонаэтого не делает.Вы можете удивиться, почему вывод типа auto имеет специальное правило для ини­циализаторов в фигурных скобках, в то время как вывод типа шаблона такого прави­ла не имеет. Но я и сам удивлен.

Увы, я не в состоянии найти убедительное объясне­ние. Но "закон есть закон", и это означает, что вы должны помнить, что если вы объяв­ляете переменную с использованием ключевого слова a u t o и инициализируете еес помощью инициализатора в фигурных скобках, то выводимым типом всегда будетstd : : i n i t i a l i z e r_l i st . Особенно важно иметь это в виду, если вы приверженец фи­лософии унифицированной инициализации - заключения и нициализирующих значе­ний в фигурные скобки как само собой разумеющегося стиля.

Классической ошибкойв С++ 1 1 является случайное объявление переменной std : : i n i t i a l i ze r_ l i s t там, где вынамеревались объявить нечто иное. Эта ловушка является одной из причин, по которымнекоторые разработчики используют фигурные скобки в инициализаторах только тог­да, когда обязаны это делать.

(Когда именно вы обязаны так поступать, мы рассмотримв разделе 3. 1 .)Что касается С++ 1 1 , то на этом история заканчивается, но для С++ 14 это еще не ко­нец. С++ 14 допускает применение auto для указания того, что возвращаемый тип функ­ции должен быть выведен (см. раздел 1 .3), а кроме того, лямбда-выражения С++ 14 могутиспользовать auto в объявлениях параметров.

Однако такое применение auto использу­ет вывод типа шаблона, а не вывод типа auto. Таким образом, функция с возвращаемымтипом auto, которая возвращает инициализатор в фигурных скобках, компилироватьсяне будет:auto createinitLi s t ( )return { 1 , 2 , 3 ) ; / / Ошибка : невозможно вывести/ / ТИП ДЛЯ { 1 , 2, 3 )То же самое справедливо и тогда, когда auto используется в спецификации типа парамет­ра в лямбда-выражении С++ 14:s td : : vector<int> v ;auto resetV =[ &v] ( cons t auto& newValue ) { vresetV ( { 1 , 2 , З } ) ;newValue; ) ; 11 C++l4/ / Ошибка : невозможно вывести/ / ТИП ДЛЯ { 1 , 2, 3 )1 .2.Вывод типа auto35Сnедует запомнить•Вывод типа auto обычно такой же, как и вывод типа шаблона, но вывод типа auto,в отличие от вывода типа шаблона, предполагает, что инициализатор в фигурныхскобках представляет s td : : i n i t i a l i ze r_ l i s t .•auto в возвращаемом типе функции или параметре лямбда-выражения влечетприменение вывода типа шаблона, а не вывода типа auto.1 .3 .

Знакомство с decl typed e c l t ypeсоздание странное. Для данного имени или выражения dec l t ype сооб­щает вам тип этого имени или выражения. Обычно то, что сообщает decl t ype,этоименно то, что вы предсказываете. Однако иногда он дает результаты, которые заставля­ют вас чесать в затылке и обращаться к справочникам или сайтам.Мы начнем с типичных случаев, в которых нет никаких подводных камней.

В отличиеот того, что происходит в процессе вывода типов для шаблонов и auto (см. разделы 1 . 1и 1 .2), decl t ype обычно попугайничает, возвращая точный тип имени или выражения,которое вы передаете ему:--const int i=О;! / decltype ( i ) - const intbool f ( const Widge t & w) ; / / decltype (w) - const Widget&11 decltype ( f ) - bool ( const Widget & )struct Point {int х, у;11};11decltype ( Point : : x ) - intdecltype ( Point : : y ) - intWidget w;11decltype (w) - Widgetif (f (w) ) ."11decltype ( f {w ) ) - booltemplate<typename Т>class vector {puЫic :11Упрощенная версия std : : vectorТ& operator [ ] ( std : : si ze_t index ) ;};vector<int> v ;if (v[O]==0 ) ".Видите� Никаких сюрпризов.36Глава 1 .

В ывод типов11decltype (v) - vector<int>/ / decltype (v [ O ] ) - int&Пожалуй, основное применение decl t уре в С++ 1 1объявление шаблонов функций,в которых возвращаемый тип функции зависит от типов ее параметров. Предположим,например, что мы хотим написать функцию, получающую контейнер, который поддер­живает индексацию с помощью квадратных скобок (т.е. с использованием " [ ] ") с индек­сом, а затем аутентифицирует пользователя перед тем как вернуть результат операциииндексации. Возвращаемый тип функции должен быть тем же, что и тип, возвращаемыйоперацией индексации.ope r a t o r [ ] для контейнера объектов типа Т обычно возвращает Т & .

Напри­мер, это так в случае s t d : : deque и почти всегда - в случае s t d : : vect or. Однакодля std : : vect or<bool> оператор operator [ ] не возвращает boo l & . Вместо этого он воз­вращает новый объект. Все "почему" и "как" данной ситуации рассматриваются в раз­деле 2.2, но главное здесь то, что возвращаемый оператором ope rator [ ] контейнера типзависит от самого контейнера.de cltype упрощает выражение этой зависимости. Вот пример, показывающий при­менение decl t уре для вычисления возвращаемого типа. Этот шаблон требует уточнения,но пока что мы его отложим.-template<typename Container, typename Index> / / Работает, ноauthAndAccess (Container& с , Index i )1 1 требуетauto- > decltype ( c [ i ] )11уточненияauthenticateUser ( J ;return c ( i ] ;Использование auto перед именем функции не имеет ничего общего с выводом типа. Насамом деле оно указывает, что использован синтаксис С++ 1 1завершающий возвраща­емый тип (trailing return type), т.е.

что возвращаемый тип функции будет объявлен по­сле списка параметров (после "->"). Завершающий возвращаемый тип обладает тем пре­имуществом, что в спецификации возвращаемого типа могут использоваться параметрыфункции. В authAndAccess, например, мы указываем возвращаемый тип с использовани­ем с и i.

Если бы возвращаемый тип, как обычно, предшествовал имени функции, с и iбыли бы в нем недоступны, поскольку в этот момент они еще не были объявлены.При таком объявлении aut hAndAc c e s s возвращает тот тип, который возвращаетope rator [ ] при применении к переданному контейнеру, в точности как мы и хотели.С++ 1 1 разрешает вывод возвращаемых типов лямбда-выражений из одной инструк­ции, а С++ 1 4 расширяет эту возможность на все лямбда-выражения и все функции,включая состоящие из множества инструкций. В случае authAndAcce s s это означает, чтов С++ 1 4 мы можем опустить завершающий возвращаемый тип, оставляя только одноведущее ключевое слово auto.

При таком объявлении auto означает, что имеет местовывод типа. В частности, это означает, что компиляторы будут выводить возвращаемыйтип функции из ее реализации:-template<typename Container, typename Index> // С++ 1 4 ;auto authAndAccess ( Container& с , Index i )1 1 Не совсем1 .3. Знакомство с decltype371 1 корректноauthenticateUser ( ) ;return c [ i ] ;/ / Возвращаемый тип выводится из c [ i ]В разделе 1 .2 поясняется, что для функций с аutо-спецификацией возвращаемого типакомпиляторы применяют вывод типа шаблона.

В данном случае это оказывается пробле­матичным. Как уже говорилось, operator [ ] для большинства контейнеров с объектамитипа Т возвращает Т&, но в разделе 1 . 1 поясняется, что в процессе вывода типа шаблона"ссылочность" инициализирующего выражения игнорируется. Рассмотрим, что это озна­чает для следующего клиентского кода:s t d : : deque<int> d;authAndAcces s (d, 5)10;/ / Аутентифицирует пользователя, воз­// вращает d [ 5 ] , затем присваивает ему1 1 значение 1 0 . Код не компилируется !Здесь d [ 5 ] возвращает i n t & , но вывод возвращаемого типа auto для authAndAccess от­брасывает ссылку, тем самым давая возвращаемый тип i n t . Этот int, будучи возвра­щаемым значением функции, является rvalue, так что приведенный выше код пытаетсяприсвоить этому rvalue типа int значение IO.

Это запрещено в С++, так что данный кодне компилируется.Чтобы заставить authAndAccess работать так, как мы хотим, нам надо использоватьдля ее возвращаемого типа вывод типа decltype, т.е. указать, что authAndAccess должнавозвращать в точности тот же тип, что и выражение с [ i ] . Защитники С++, предвидя не­обходимость использования в некоторых случаях правил вывода типа decl t уре, сделали этовозможным в С++ \ 4 с помощью спецификатора decltype ( auto ) .

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

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

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

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