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

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

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

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

Рассмотрим следующуюфункцию-член push_back в std : : vector:template<class Т,al locator<T>> / / Из стандарта С++class Allocatorclass vector {puЫ i c :void push_back ( T&& х ) ;};Параметр push_back, определенно, имеет верный для универсальной ссылки вид, нов данном случае вывода типа нет.

Дело в том, что push_back не может существовать безконкретного инстанцированного вектора, частью которого он является; а тип этого ин­станцирования полностью определяет объявление push_back. Другими словами, кодstd : : vector<Widget> v;5.2.Отличие универсальных ссылок от rvalue-cc ыл oк1 73приводит к следующему инстанцированию шаблона std : : ve ctor:class vector<Widget , allocator<Widget>> {puЫ i c :/ / rvalue - ccьmкavoid push_back (Widget&& х ) ;};Теперь вы можете ясно видеть, что push_bac k не использует вывода типа.

Эта функцияpush_back для vector<T> (их две - данная функция перегружена) всегда объявляет па­раметр типа "rvalue-ccылкa на т ".В противоположность этому концептуально подобная функция-член ernplace_backв std : : vector выполняет вывод типа:template<class Т ,class Al locatorallocator<T>> / / / / Из стандарта С++cla s s vectorpuЬl i c :t emplate <class .

. . Args>void emplace_back (Args&& . . . a rgs ) ;};Здесь параметр типа Args не зависит от параметра типа вектора Т, так что Args дол­жен выводиться при каждом вызове ernpl ace_back. (Да, в действительности Args пред­ставляет собой набор параметров, а не параметр типа, но для нашего рассмотрения егоможно рассматривать как параметр типа.)Тот факт, что параметр типа ernplace back имеет имя Args и является при этом уни­версальным указателем, только усиливает мое замечание о том, что универсальная ссыл­ка обязана иметь вид "Т& &': Вы не обязаны использовать в качестве имени т.

Например,приведенный далее шаблон принимает универсальную ссылку, поскольку она имеет пра­вильный вид ( " t yp e & &" ) , а тип pararn выводится (опять же, исключая крайний случай,когда вызывающий код явно указывает тип):_template<typename MyTemplateType>1 1 param являетсяvoid someFunc (МyТemplateТype&& param ) ; / / универсальной ссьmкойРанее я отмечал, что переменные auto также могут быть универсальными ссылками.Чтобы быть более точным, переменные, объявленные с типом aut o & & , являются универ­сальными ссылками, поскольку имеет место вывод типа и они имеют правильный вид(" Т & & " ) .

Универсальные ссылки auto не так распространены, как универсальные ссылки,используемые в качестве параметров шаблонов функций, но они также время от временивозникают в C++ l l . Гораздо чаще они возникают в C++ l4, поскольку лямбда-выраженияС++ 1 4 могут объявлять параметры aut o & &. Например, если вы хотите написать лямбда­выражение С++ 14 для записи времени, которое занимает вызов произвольной функции,можете сделать это следующим образом:1 74Гnа ва S. Rvalue-ccыnки, семантика перемещений и прямая передачаauto timeFuncinvocation =[ ] ( auto&& func, auto&& .

. . params )/ / С++ 1 4Запуск таймера ;/ / Вызов funcstd: : forward<decltype ( func) > ( func) (std : : forward<decltype (params ) > (params ) . . . / / с params);Оста нов таймера и запись време ни ;);Если ваша реакция на код "std : : forward<decltype (ля -ля-ля ) > " внутри лямбда-вы­ражения - "Что за @#$%?!!'; то, вероятно, вы просто еще не читали раздел 6.3.

Не беспо­койтесь о нем. Главное для нас сейчас в этом лямбда-выражении - объявленные как auto&&параметры. func является универсальной ссылкой, которая может быть связана с любымвызываемым объектом, как lvalue, так и rvalue. params представляет собой нуль или несколь­ко универсальных ссылок (т.е. набор параметров, являющихся универсальными ссылками),которые могут быть связаны с любым количеством объектов произвольных типов. В резуль­тате, благодаря универсальным ссылкам auto, лямбда-выражение t imeFuncinvocation в со­стоянии записать время работы почти любого выполнения функции.

(Чтобы разобратьсяв разнице между "любого" и "почти любого'; обратитесь к разделу 5.8.)Имейте в виду, что весь этот раздел - основы универсальных ссылок - являетсялож . . . простите, абстракцией. Лежащая в основе истина, известная как свертывание ссы­лок (reference collapsing), является темой раздела 5.6. Но истина не делает абстракциюменее полезной. Понимание различий между rvаluе-ссылками и универсальными ссыл­ками поможет вам читать исходные тексты более точно ("Этот Т & & связывается толькос rvalue или с чем утодно?"), а также избегать неоднозначностей при общении с колле­гами ("Здесь я использовал универсальную ссылку, а не rvalue-ccылкy. .

."). Оно такжепоможет вам в понимании смысла разделов 5.3 и 5.4, которые опираются на указанноеразличие. Так что примите эту абстракцию, погрузитесь в нее . . . Так же как законы Нью­тона (технически не совсем корректные) обычно куда полезнее и проще общей теорииотносительности Эйнштейна ("истины"), так и понятие универсальных ссылок обычнопредпочтительнее для работы, чем детальная информация о свертывании ссылок.Сnедует запомнить•Если параметр шаблона функции имеет тип т & & для выводимого типа Т или еслиобъект объявлен с использованием aut o & & , то параметр или объект является уни­версальной ссылкой.•Если вид объявления типа не является в точности t уре & & или если вывод типа неимеет места, то t уре & & означает rvalue-ccылкy.•Универсальные ссылки соответствуют rvаluе-ссылкам, если они инициализируютсязначениями rvalue. Они соответствуют lvаluе-ссылкам, если они инициализируютсязначениями lvalue.5.2.Отл ичие универсальных ссылок от rvalue-ccылoк1 75S.3.

Испопьзуйте s td : : move дпя rvalue - ccыno к,дпя универсапьных ссыпока std : : forward-Rvаluе-ссылки связываются только с объектами, являющимися кандидатами для пе­ремещения. Если у вас есть параметр, представляющий собой rvalue-ccылкy, вы знаете,что связанный с ним объект может быть перемещен:class Widget {Widget (Widget&& rhs ) ; / / rhs, определенно, ссьmается на11 объект, который можно перемещать};В этом случае вы захотите передавать подобные объекты друтим функциям таким об­разом, чтобы разрешить им использовать преимущества "правосторонности". Способ,которым это можно сделать, - привести параметры, связываемые с такими объектами,к rvalue. Как поясняется в разделе 5.

1 , std : : move не просто это делает, это та задача,для которой создана эта функция:class Widget {puЫ ic :// rhs является rvalue-ccьmкoйWidget (Widge t & & rhs ): пате (std: : move (rhs . name) ) ,р (std: : move (rhs .р) ){}".private :std : : string name;std : : shared_ptr<SomeDataStructure> р ;};С друтой стороны, универсальная ссылка (см.

раздел 5.2) может быть связана с объек­том, который разрешено перемещать. Универсальные ссылки должны быть приведенык rvalue только тогда, когда они были инициализированы с помощью rvalue. В разделе 5.1разъясняется, что именно это и делает функция std: : for ward:class Widget {puЫ i c :template<typename Т>void setName ( T & & newName )/ / newName является{ name std: : forward<Т> (newName) ; } / / универсальной ссьmкой=};Короче говоря, rvаluе-ссылки при их передаче в друтие функции должны быть безус­ловно приведены к rvalue (с помощью s t d : : move), так как они всегда связываются с rvalue,а универсальные ссылки должны приводиться к rvalue при их передаче условно (с помо­щью s t d : : forward), поскольку они только иногда связываются с rvalue.1 76Глава 5. Rv а luе-ссы лки, семантика перемещений и прямая передачаВ разделе 5.1 поясняется, что можно добиться верного поведения rvalue-ccылoк и спомощью s t d : : fo rward, но исходный текст при этом становится многословным, под­верженным ошибкам и неидиоматичным, так что вы должны избегать примененияstd : : forward с rvаluе-ссылкам.

Еще худшей является идея применения std : : move к уни­версальным ссылкам, так как это может привести к неожиданному изменению значенийlvalue (например, локальных переменных):class Widget {puЫ i c :template<typename Т>void setName ( T&& newName ){ narnestd: : move (newName) ;/ / Универсальная ссылка .11 Компилируется, но это=11 очень плохое решение !private :std: : string name ;std: : shared_ptr<SomeDataSt ructure> р ;};std : : string getWidgetName ( ) ; / / Фабричная функцияWidget w;11 nлокальная переменнаяauto n = getWidgetName ( ) ;/ / Перемещение n в w 1w . se tName ( n ) ;11 Значение n теперь неизвестно-Здесь локальная переменная n передается функции w .

s e t N arne . Вызывающий кодможно простить за предположение о том, что эта функция по отношению к n являетсяоперацией чтения. Но поскольку setNarne внутренне использует std : : move для безуслов­ного приведения своего ссылочного параметра к rvalue, значение n может быть переме­щено в w . name, и n вернется из вызова setName с неопределенным значением.

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

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

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

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