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

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

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

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

С чисто техническойточки зрения ответ утвердительный: s t d : : forward может сделать все. Необходимостив std : : move нет. Конечно, ни одна из этих функций не является действительно необход и­мой, потому что мы могли бы просто вручную написать требуемое приведение, но, я на­деюсь, мы сойдемся во мнении, что это будет как минимум некрасиво.Привлекательными сторонами s t d : : move являются удобство, снижение вероятнос­ти ошибок и большая ясность. Рассмотрим класс, в котором мы хотели бы отслеживатьколичество вызовов перемещающего конструктора.

Все, что нам надо, - это счетчик,объявленный как stat i c, который увеличивался бы при каждом вызове перемещающе­го конструктора. Полагая, что единственными нестатическими данными класса являетсяstd : : string, вот как выглядит обычный (т.е. использующий std : : move ) способ реализа­ции перемещающего конструктора:-class Widget {puЬl i c :Widget (Widget & & rhs )s ( std: : шove ( rhs . s ) ){ ++rnoveCtorCa l l s ; 1private :static std: : s i ze t moveCtorCa l l s ;s t d : : st ring s ;1;Чтобы реализовать то же поведение с помощью s t d : : forward, код должен был бы вы­глядеть следующим образом:class Widget {puЫic :Widget ( Widget&& rhs )/ / Безусловная,s ( std: : forward<std : : string> ( rhs .

s ) ) / / нежела тельная++rnoveCtorCal l s ; 111 реализация};Заметим сначала, что s t d : : move требует только аргумент функции ( rhs . s ) , в товремя как s t d : : forward требует как аргумент функции ( rhs . s ) , так и аргумент типа1 70Гnава 5. Rvalue-ccыnки, семантика перемещений и прямая передачашаблона ( std : : string ) . Затем обратим внимание на то, что тип, который мы передаемs t d : : forward, должен быть не ссылочным, поскольку таково соглашение по кодирова­нию, что передаваемый аргумент является rvalue (см. раздел 5.6). Вместе это означает,что std : : move требует меньшего ввода текста по сравнению с s t d : : forward и избавляетот проблем передачи типа аргумента, указывающего, что передаваемый аргумент являет­ся rvalue. s t d : : move устраняет также возможность передачи неверного типа (например,std: : string&, что привело бы к тому, что член-данные s был бы создан с помощью ко­пирования, а не перемещения).Что еще более важно, так это то, что использование s t d : : move выполняет безуслов­ное приведение к rvalue, в то время как использование s t d : : forward означает приведе­ние к rvalue только ссылок, связанных с rvalue.

Это два совершенно различных действия.Первое из них обычно настраивает перемещение, в то время как второе просто передаетобъект другой функции способом, сохраняющим исходную характеристику объекта (lvalueили rvalue). Поскольку эти действия совершенно различны, наличие двух разных функций(и разных имен функций) является преимуществом, позволяющим их различать.Следует запомн ить•std : : move выполняет безусловное приведение к rvalue. Сама по себе эта функция неперемещает ничего.•std : : forward приводит свой аргумент к rvalue только тогда, когда этот аргументсвязан с rvalue.•Ни std : : move, ни s t d : : forward не выполняют никаких действий времени выпол­нения.5 .2.

Отnичие универса n ьны х ссыnок от rvalue-ccыno кГоворят, что истина делает нас свободными, но при соответствующих обстоятельстваххорошо выбранная ложь может оказаться столь же освобождающей. Этот раздел и естьтакой ложью. Но поскольку мы имеем дело с программным обеспечением, давайте из­бегать слова "ложь': а вместо него говорить, что данный раздел содержит "абстракцию".Чтобы объявить rvalue-ccылкy на некоторый тип Т, вы пишете Т & &. Таким образом,представляется разумным предположить, что если вы видите в исходном тексте Т & & , тоимеете дело с rvаluе-ссылками. Увы, не все так просто.void f (Widget&& pa ram) ;1 1 rvalue - ccылкaWidget&& varl1 1 rvalue - ccылкaauto&& var2=Widget ( ) ;varl ;1 1 Не rvalue - ccылкatemplate<typename Т>void f ( std: : vector<T>&& param) ; // rvalue - ccылкa5.2.Отличие универсальных ссылок от rvalue-cc ыл o к1 71ternplate<typenarne Т>void f ( T&& pararn) ;1 1 Не rvalue - ccылкaНа самом деле "т & & " имеет два разных значения.

Одно из них - конечно, rvа\uе-ссылка.Такие ссылки ведут себя именно так, как вы ожидаете: они связываются только с rvalueи их смь1сл заключается в идентификации объектов, которые могут быть перемещены.Другое значение "Т& & " ли бо rvа\uе-ссылка, ли бо \vа\uе-ссылка. Такие ссылки выгля­дят в исходном тексте как rvа\uе-ссылки (т.е. "т& &"), но могут вести себя так, как еслибы они были \vа\uе-ссылками (т.е.

"т&"). Такая дуальная природа позволяет им быть свя­занными как с rvalue (подобно rvа\uе-ссылкам), так и с lvalue (подобно \vа\uе-ссылкам).Кроме того, они могут быть связаны как с константными, так и с неконстантными объек­тами, как с объектами volat i l e, так и с объектами, не являющимися volat i le, и дажес объектами, одновременно являющимися и const, и volat i le.

Они могут быть связаныпрактически со всем. Такие беспрецедентно гибкие ссылки заслуживают собственногоимени, и я называю их универсальными ссылками 1 •Универсальные ссылки возникают в двух контекстах. Наиболее распространеннымявляются параметры шаблона функции, такие как в приведенном выше примере кода:-ternplate<typenarne Т>void f ( Т&& pararn) ;// pararn - универсальная ссылкаВторым контекстом являются объявления auto, включая объявление из приведенноговыше примера кода:auto&& var2 ; var l ;/ / var2 - универсальная ссылкаОбщее в этих контекстах - наличие вывода типа. В шаблоне f выводится тип pararn,а в объявлении var2 выводится тип переменной var2. Сравните это с приведенными далеепримерами (также взятыми из приведенного выше примера кода), в которых вывод типаотсутствует. Если вы видите "т & & " без вывода типа, то вы смотрите на rvа\uе-ссылку://11Widge t && varl ; Widget ( ) ; / /11void f (Widget&& pararn) ;Вывод типа отсутствует;pararn - rvalue-ccылкaВывод типа отсутствует;varl - rvalue-ccьшкaПоскольку универсальные ссылки являются ссылками, они должны быть инициализи­рованы.

Инициализатор универсальной ссылки определяет, какую ссылку она представля­ет: \vа\uе-ссылку или rvа\uе-ссылку. Если инициализатор представляет собой rvalue, уни­версальная ссылка соответствует rvа\uе-ссылке. Если же инициализатор является lvalue,универсальная ссылка соответствует \vа\uе-ссылке. Для универсальных ссылок, которыеявляются параметрами функций, инициализатор предоставляется в месте вызова:ternplate<typenarne Т>void f (T&& pararn) ; // pararn является универсальной ссьшкой1 В разделе 5.3 поясняется, что к универсальным ссылкам почти всегда может применятьсяstd : : forward, так что, когда эта книга готовилась к печати, некоторые члены сообщества С++начинали именовать универсапьные ссыпки передаваемыми ссылками.1 72Глава 5. Rvаluе-ссылки, семантика леремещений и прямая передачаWidget w;f (W) ;/ / В f передается lvalue; тип param // Widge t& ( т .

е . lvalue - ccылкa )f ( std: : move (w) ) ;/ / В f передается rvalue; тип param 11 Widge t & & ( т . е . rvalue-ccыпкa )Чтобы ссылка была универсальной, вывод типа необходим, но не достаточен. Видобъявления ссылки также должен быть корректным, и этот вид достаточно ограничен.Он должен в точности имеет вид "т & & ': Взглянем еще раз на пример, который мы ужерассматривали ранее:template<typename Т>void f ( std: : vector<T>&& param ) ; / / param - rvalue - ccылкaКогда вызывается f, тип т выводится (если только вызывающий код явно его не укажет,но этот крайний случай мы не рассматриваем). Однако объявление типа param не имеет вида"т& &"; оно представляет собой std : : vector<T>& &.

Это исключает возможность для paramбыть универсальной ссылкой. Следовательно, param является rvаluе-ссылкой, что ваши ком­пиляторы с удовольствием подтвердят при попытке передать в функцию f lvalue:std : : vector< int> v;f (V) ;11 Ошибка ! Невозможно связать lvalue11 с rvаluе - ссылкойДаже простого наличия квалификатора coпst достаточно для того, чтобы отобратьу ссылки звание универсальной:template<typename Т>void f ( const Т&& param ) ; // param - rvalue - ccылкaЕсли вы находитесь в шаблоне и видите параметр функции с типом "т& &': вы можетерешить, что перед вами универсальная ссылка. Но вы не должны этого делать, посколь­ку размещение в шаблоне не гарантирует наличие вывода типа.

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

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

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

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