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

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

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

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

То, что изначально можетпоказаться противоречием (decltype и auto?), в действительности имеет смысл: auto указы­вает, что тип должен быть выведен, а decltype говорит о том, что в процессе вывода следуетиспользовать правила decltype. Итак, можно записать authAndAccess следующим образом:template<typename Container, t ypename Index> / /////authAndAccess ( Contai ner& с, I ndex i )//authent icateUser ( ) ;return c [ i ] ;declt:ype (auto)С++ 1 4 ; работает,но все ещетребуетуточненияТеперь authAndAccess действительно возвращает то же, что и с [ i ] .

В частности, в распро­страненном случае, когда с [ i ] возвращает Т & , authAndAccess также возвращает Т&, и в томредком случае, когда с [ i ] возвращает объект, authAndAccess также возвращает объект.Использование decltype ( auto) не ограничивается возвращаемыми типами функций.Это также может быть удобно для объявления переменных, когда вы хотите применятьправила вывода типа decltype к инициализирующему выражению:38Гnава 1 . Вывод типовWidget w;const Widget& cw = w;auto myWidgetl = cw;1111declt:ype (auto) myWidget2Вывод типа auto :тип myWidgetl - Widgetcw; // Вывод типа decltype :1 1 тип myWidget2 - coпst Widget &Я знаю, что вас беспокоят два момента. Один из них - упомянутое выше, но пока неописанное уточнение authAndAccess.

Давайте, наконец-то, разберемся в этом вопросе.Еще раз посмотрим на версию aut hAndAcce s s в С++ 1 4:template<typename Container, typename Index>decltype ( auto) authAndAcces s ( Container& с, Index i ) ;Контейнер передается как lvalue-ccылкa на неконстантный объект, поскольку возвращае­мая ссылка на элемент контейнера позволяет клиенту модифицировать этот контейнер. Ноэто означает, что этой функции невозможно передавать контейнеры, являющиеся rvalue.rvalue невозможно связать с lvаluе-ссылками (если только они не являются lvаluе-ссылкамина константные объекты, что в данном случае очевидным образом не выполняется).Надо сказать, что передача контейнера, являющегося rvalue, в aut hAndAcce s s явля­ется крайним случаем. Такой rvаluе-контейнер, будучи временным объектом, обычноуничтожается в конце инструкции, содержащей вызов authAndAcce ss, а это означает, чтоссылка на элемент в таком контейнере (то, что должна вернуть функция authAndAccess)окажется "висячей" в конце создавшей ее инструкции.

Тем не менее передача временногообъекта функции aut hAndAcces s может иметь смысл. Например, клиент может простохотеть сделать копию элемента во временном контейнере:std : : deque< std : : string> makeStringDeque ( ) ; 11 Фабричная функция/ / Делаем копию пятого элемента deque, возвращаемого11 функцией makeStringDequeauto s = authAndAcces s (makeStringDeque ( ) , 5 ) ;Поддержка такого использования означает, что мы должны пересмотреть объявлениефункции authAndAccess, которая должна принимать как lvalue, так и rvallle.

Можно ис­пользовать перегрузку (одна функция объявлена с параметром, представляющим собойlvalue-ccылкy, а вторая - с параметром, представляющим собой rvalue-ccылкy), но тогданам придется поддерживать две функции. Избежать этого можно, если у нас будет функ­ция authAndAccess, использующая ссылочный параметр, который может быть связан какс lvalue, так и с rvalue, и в разделе 5.2 поясняется, что это именно то, что делают универсаль­ные ссылки.

Таким образом, authAndAccess может быть объявлена следующим образом:template<typename Container, typename Index> / / Теперь с decltype ( auto) authAndAccess ( Container&& с, / / универсальнаяIndex i ) ;/ / ссылка1 .3. Знакомство с decltype39В этом шаблоне мы не знаем, с каким типом контейнера работаем, и точно так же незнаем тип используемых им индексных объектов. Использование передачи по значениюдля объектов неизвестного типа обычно сопровождается риском снижения произво­дительности из-за ненужного копирования, проблемами со срезкой объектов (см. раз­дел 8.1) и насмешками коллег.

Но в случае индексов контейнеров, следуя примеру стан­дартной библиотеки для значений индексов (например, в operator [ ] для s t d : : st ring,std : : vector и s t d : : de que) это решение представляется разумным, так что мы будемпридерживаться для них передачи по значению.Однако нам нужно обновить реализацию шаблона для приведения его в соответствиес предостережениями из раздела 5.3 о применении std : : forward к универсальным ссылкам:template<typename Container, typename Index> / / Окончательнаяdecltype (auto)/ / версия для/ / С++14authAnd.Acces s ( Container&& с , Index i )authenticateUser ( ) ;return std: : forward<Container> (c) [ i ) ;Этот код должен делать все, что мы хотели, но он требует компилятора С++ 14.

Если у васнет такового, вам следует использовать версию шаблона для С++ 1 1 . Она такая же, каки ее аналог С++ 1 4, за исключением того, что вы должны самостоятельно указать воз­вращаемый тип:template<typename Container, typename Index> / / Окончательная/ / версия дляautoauthAnd.Acces s ( Container&& с, Index i )/ / C++ l l-> decl type ( std : : forward<Container> (с) [ i ] )(authenticateUser ( ) ;return std : : forward<Conta iner> ( с ) [ i ) ;Вторым беспокоящим моментом является мое замечание в начале этого раздела о том,что decl t уре почти всегда дает тип, который вы ожидаете, т.е. что он редко преподноситсюрпризы.

По правде говоря, вряд ли вы столкнетесь с этими исключениями из правила,если только вы не занимаетесь круглосуточно написанием библиотек.Чтобы полностью понимать поведение dec l t ype, вы должны познакомиться с неко­торыми особыми случаями. Большинство из них слишком невразумительны, чтобы бытьразмещенными в этой книге, но один из них приводит к лучшему пониманию decl typeи его применения.Применение de c l t ype к имени дает объявленный тип для этого имени.

Имена пред­ставляют собой lvаluе-выражения, но это не влияет на поведение decl t ype. Однакодля lvаluе-выражений, более сложных, чем имена, decl t ype гарантирует, что возвраща­емый тип всегда будет lvаluе-ссылкой. Иначе говоря, если lvаluе-выражение, отличноеот имени, имеет тип Т, то decl type сообщает об этом типе как об Т&. Это редко на что-то40Гл ава 1 . Вывод типоввлияет, поскольку тип большинства lvаluе-выражений в обязательном порядке включаетквалификатор lvаluе-ссылки. Например, функции, возвращающие lvalue, всегда возвра­щают lvаluе-ссылки.Однако у этого поведения есть следствия, о которых необходимо знать. В кодеint х=О;является именем переменной, так что dec l t ype ( х ) представляет собой i n t .

Однако"заворачивание" имени х в скобки - " ( х ) " - дает выражение, более сложное, чем имя.Будучи именем, х представляет собой lvalue, и С++ также определяет выражение ( х ) какlvalue. Следовательно, declt ype ( ( х ) ) представляет собой i n t & . Добавление скобок во­круг имени может изменить тип, возвращаемы й для него decl t ype !В C++ l l это просто любопытный факт, но в сочетании с поддержкой в С++ 14dec l t ype ( auto) это означает, что, казалось бы, тривиальные изменения в способе запи­си инструкции return могут повлиять на выводимый тип функции:хdecltype (auto)f1 ( ){int х=О;return х;decl type (auto)11 decltype ( x ) представляет собой int ,// так что fl возвращает intf2 ( ){int х=О;return (х);/ / decltype ( ( x) ) представляет собой int & ,/ / так что f2 возвращает int&Обратите внимание, что f2 не только имеет возвращаемый тип, отличный от fl, нои возвращает ссылку на локальную переменную! Этот код ведет вас к неопределенномуповедению, что вряд ли является вашей целью.Основной урок состоит в том, чтобы при использовании dec l t ype ( a u t o ) уделятьдеталям самое пристальное внимание.

Кажущиеся совершенно незначительными дета­ли в выражении, для которого выводится тип, могут существенно повлиять на тип, воз­вращаемый dec l t ype ( auto ) . Чтобы гарантировать, что выводимый тип - именно тот,который вы ожидаете, используйте методы, описанные в разделе 1 .4.В то же время не забывайте и о более широкой перспективе. Конечно, declt ype (какавтономный, так и в сочетании с auto ) при выводе типов иногда может привести к сюр­призам, но это не нормальная ситуация.

Как правило, dec l t ype возвращает тот тип, ко­торый вы ожидаете. Это особенно верно, когда dec l t ype применяется к именам, потомучто в этом случае dec l t ype делает именно то, что скрывается в его названии: сообщаетобъявленный тип (declared type) имени.1 .3. Знакомство с decltype41Следует запомнить•dec l t ype почти всегда дает тип переменной или выражения без каких-либо из­менений.•Для lvаluе-выражений типа т, отличных от имени, declt ype всегда дает тип Т &.•C++ l 4 поддерживает конструкцию decltype ( auto ) , которая, подобно auto, выво­дит тип из его инициализатора, но выполняет вывод типа с использованием пра­вил dec l t ype.1 .4. Как просмотреть выведенные типыВыбор инструментов для просмотра результатов вывода типа зависит от фазы про­цесса разработки программного обеспечения, на которой вы хотите получить эту инфор­мацию.

Мы рассмотрим три возможности: получение информации о выводе типа приредактировании кода, во время компиляции и во время выполнения.Редакторы IDEРедакторы исходных текстов в IDE часто показывают типы программных сущностей(например, переменных, параметров, функций и т.п.), когда вы, например, помещаетеуказатель мыши над ними. Например, пусть у вас есть кодconst int theAnswer = 4 2 ;theAnswer;auto хauto у = &theAnswer;Редактор, скорее всего, покажет, что выведенный тип х представляет собой int, а выве­денный тип у - const int * .Чтобы это сработало, ваш код должен быть в более-менее компилируемом состоянии,поскольку такого рода информация поставляется среде разработки компилятором С++(или как минимум его клиентской частью}, работающим в IDE.

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

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

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

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