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

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

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

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

Чтобы этого не произошло, к Т применяется свойство типа(см. раздел 3.3) s t d : : remove_reference, тем самым обеспечивая применение " & &" к типу,не являющемуся ссылкой. Это гарантирует, что s t d : : move действительно возвращаетrvа\uе-ссылку, и это важно, поскольку rvа\uе-ссылки, возвращаемые функциями, явля­ются rvalue. Таким образом, std : : move приводит свой аргумент к rvalue, и это все, чтоона делает.В качестве небольшого отступления скажем, что s td : : move можно реализоватьв С++ 14 меньшими усилиями. Благодаря выводу возвращаемого типа функции (см.

раз­дел 1 .3) и шаблону псевдонима s t d : : remove_reference_t (см. раздел 3.3) std : : moveможно записать следующим образом:// С++1 4 ; находится вtemplate<typename Т>move ( T & & param) / / пространстве имен stddecltype (auto)[using ReturnType ramove_reference_t<T>& & ;return static_cast<ReturnType> (param) ;=Легче для восприятия, не так ли?Поскольку s t d : : move ничего не делает, кроме приведения своего аргумента к rvalue,были предложения дать этому шаблону другое имя, например rva lue_cas t .

Как бытам ни было, у нас имеется имя std : : move, так что нам важно запомнить, что это имяstd : : move делает и чего не делает. Итак, оно выполняет приведение. И оно ничего непереносит.Конечно, rvalue являются кандидатами на перемещение, поэтому применениеstd : : move для объекта сообщает компилятору, что объект предназначается для пере­мещения. Вот почему std : : move имеет такое имя: чтобы легко распознавать объекты,которые могут быть перемещены.По правде говоря, rvalue обь1чно являются всего лишь кандидатами для перемещения.Предположим, что вы пишете класс, представляющий аннотации. Конструктор классаполучает параметр s t d : : st ring, представляющий аннотацию, и копирует значение пара­метра в член-данные. С учетом информации из раздела 8 .

1 вы объявляете параметр какпередаваемый по значению:class Annotatioп {puЫ i c :explicit Annotation ( std: : strinq text ) ; / / Параметр};11 копируемый , так что согласно/ / разделу 8 . 1 он передается по значениюНо конструктору Annotation требуется только прочесть значение text. Ему не нужно егомодифицировать.

В соответствии с освященной веками традицией использования cons tвезде, где только можно, в ы переписываете свое объявление, делая text константой:class AnnotationpuЫic :5.1 .Аэы std::move и std::forward1 67explicit Annotation ( const std: : s t ring text ) ;};Чтобы избежать дорогостоящей операции копирования t ext в член-данные, вы оставля­ете в силе совет из раздела 8 . 1 и применяете std : : move к text, тем самым получая rvalue:class Annotation (puЫ i c :explicit Annotat ion ( const s t d : : st ring text )value (std: : move (text) )11 " Перемещение" text в value ;11 этот код не делает того ,( ...

}/ / что от него ожидается !private :std : : string va lue;};Этот код компилируется. Этот код компонуется. Этот код выполняется. Этот кодустанавливает значение члена-данных va lue равным содержимому строки text. Един­ственное, что отличает этот код от идеальной реализации ваших намерений, - то, чтоtext не перемещается в va l ue, а копируется. Конечно, text приводится к rvalue с помо­щью s t d : : move, но text объявлен как const std : : st r i ng, так что перед приведениемtext являлся lvalue типа const s t d : : st r ing, так что результатом приведения являетсяrvalue типа const std : : s t r i ng, и на протяжении всех этих действий константность со­храняется.Рассмотрим, как компиляторы определяют, какой из конструкторов std : : st ring дол­жен быть вызван.

Есть две возможности:class stringpuЬl i c :1 1 s t d : : st ring в действительности представляет// собой typedef для std : : basic_string<char>string ( const string& rhs ) ; / / Копирующий конструкторstring ( string&& rhs ) ;/ / Перемещающий конструктор};В списке инициализации членов конструктора Annotat i on результатом s td : : move( text ) является rvalue типа const std : : st r i ng. Это rvalue нельзя передать перемеща­ющему конструктору s t d : : s t r i ng, поскольку перемещающий конструктор получаетrvalue-ccылкy на неконстантную s t d : : s t r ing. Однако это rvalue может быть переда­но копирующему конструктору.

поскольку lvalue-ccылкy на const разрешено связыватьс константным rvalue. Таким образом, инициализация члена использует копирующийконструктор s t d : : s t r i ng, несмотря на то что text был приведен к rvalue! Такое пове­дение имеет важное значение для поддержания корректности const. Перемещение зна­чения из объекта в общем случае модифицирует этот объект, так что язык программи­рования должен не разрешать передавать константные объекты в функции (такие, какперемещающие конструкторы), которые могут их модифицировать.168Глава 5. Rvа l uе-ссыл ки, семантика перемещений и прямая передачаИз этого примера следует извлечь два урока.

Во-первых, не объявляйте объекты какконстантные, если хотите иметь возможность выполнять перемещение из н их. Запросперемещения к константным объектам молча трансформируется в копирующие опера­ции. Во-вторых, std : : move не только ничего не перемещает самостоятельно, но даже негарантирует, что приведенный этой функцией объект будет иметь право быть переме­щенным. Единственное, что точно известно о результате применения s t d : : move к объ­екту, - это то, что он является rvalue.История с std : : forward подобна истории с std : : move, но тогда как s t d : : move вы­полняет безоговорочное приведение своего аргумента в rvalue, std : : forward делает этотолько при определенных условиях.

std : : forward является условным приведением. Что­бы понять, когда приведение выполняется, а когда нет, вспомним, как обычно использу­ется std : : forward. Наиболее распространенным сценарием является тот, когда шаблонфункции получает параметр, представляющий собой универсальную ссылку, и которыйпередается другой функции:void process ( const Widget& lvalArg) ; 11 Обработка lvaluevoid process (Widget&& rvalArg ) ;1 1 Обработка rvaluetemplate<typename Т>void logAndProces s ( T & & param)11 шаблон, передающий1 1 param на обработкуauto now =1 1 Получает текущее времяstd : : chrono : : system_clock : : now ( ) ;makeLogEntry ( "Bызoв ' process ' " , now) ;process ( std : : forward<T> ( param) ) ;Рассмотрим два вызова logAndProcess, один с lvalue, а другой - с rvalue:Widget w ;logAndProcess (w) ;1 1 Вызов с lvaluelogAndProcess ( s td : : move ( w ) ) ; 11 Вызов с rvalueВ функции logAndProcess параметр param передается функции process.

Функцияprocess перегружена для lvalue и rvalt1e. Вызывая logAndProces s с lvalue, мы, есте­ственно, ожидаем, что lvalue будет передано функции process как lvalue, а вызываяlogAndProcess с rvalue, мы ожидаем, что будет вызвана перегрузка process для rvalue.Однако pa ram, как и все параметры функций, является lvalue.

Каждый вызов processвнутри logAndProcess будет, таким образом, вызывать перегрузку process для lvalue. Дляпредотвращения такого поведения нам нужен механизм для приведения param к rvalueтогда и только тогда, когда аргумент, которым инициализируется param аргумент, пе­реданный logAndProcess,был rvalue. Именно этим и занимается std : : forward. Вотпочему std : : forward представляет собой условное приведение: эта функция выполняетприведение к rvalue только тогда, когда ее аргумент инициализирован rvalue.--5.1 .

Азы std::move и std::forward169Вы можете удивиться, откуда std : : forward может знать, был ли ее аргумент инициа­лизирован rvalue? Например, как в приведенном выше коде s t d : : forward может сказать,был ли param инициализирован с помощью lvalue или rvalue? Краткий ответ заключаетсяв том, что эта информация кодируется в параметре Т шаблона logAndProcess. Этот пара­метр передается s t d : : forward, которая восстанавливает закодированную информацию.Детальное описание того, как работает данный механизм, вы найдете в разделе 5.6.Учитывая, что и s t d : : move, и s t d : : forward сводятся к приведению и единствен­ная разница между ними лишь в том, что s t d : : move всегда выполняет приведение, в товремя как s t d : : forwardтолько иногда, вы можете спросить, не можем ли мы обой­тись без s t d : : move и просто использовать везде s t d : : f o rward.

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

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

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

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