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

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

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

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

Если вы читали его дав­но или вовсе не читали, просмотрите указанный раздел, прежде чем читать данный.Отказ от пе р еr рузк иВ первом примере раздела 5.4 функция logAndAdd является типичным представи­телем функций, которые могут избежать недостатков перегрузки для универсальныхссылок, просто используя разные имена для потенциальных перегрузок. Например,рассматривавшиеся перегрузки l ogAndAdd могут быть разделены на logAndAddNameи logAndAddNameidx. Увы, этот подход не будет работать для второго рассматривавшего­ся примера - конструктора Person, потому что имена конструкторов в языке зафикси­рованы.

Кроме того, кто же захочет отказаться от перегрузки�Пе р едача cons t т &Одной из альтернатив является возврат к С++98 и замена передачи универсальнойссылки передачей lvаluе-ссылки на const. Фактически это первый подход, рассматривав­шийся в разделе 5.4. Его недостаток состоит в том, что данный дизайн не столь эффекти­вен, как нам хотелось бы. С учетом всех нынешних наших знаний о взаимодействии уни­версальных ссылок и перегрузки отказ от некоторой эффективности в пользу простотыможет оказаться более привлекательными компромиссом, чем нам казалось изначально.Пе редача по значен и юПодход, который часто позволяет добиться производительности без увеличениясложности, заключается в замене передачи параметров по ссылке передачей по значению,как бы противоестественно это ни звучало. Этот дизайн основан на совете из раздела 8.

1 :рассмотреть вопрос о передаче объектов п о значению в случае, когда известно, что онибудут копироваться. Поэтому я отложу до указанного раздела подробное обсуждениетого, как все это работает и насколько эффективным является это решение. Здесь я про­сто покажу, как этот подход может использоваться в примере с классом Person:class PersonpuЫ i c :1 90Глава 5.

Rvаluе-ссылки, семантика перемещений и п рямая передачаexpl icit Person ( std : : string n ) / ///: name ( std : : move ( n ) ) { 111//explicit Person ( int idx f: name ( nameFromidx ( idx ) ) 1 1Замена конструктора с Т & & ;о применении std: : moveчитайте в разделе 8 . 1Как и ранееprivate :std : : string name ;f;Поскольку конструктора s t d : : st r i ng, принимающего только целочисленное значение,нет, все аргументы типа i nt и подобных ему (например, std : : s i ze_ t, short, l ong), пере­даваемые конструктору Person, будут перенаправлены к перегрузке для int.

Аналогично всеаргументы типа std : : string (а также аргументы, из которых могут быть созданы объектыstd: : string, например литералы наподобие "Ruth" ) будут передаваться конструктору, при­нимающему std : : string. Здесь для вызывающего кода нет никаких сюрпризов. Возможно,некоторые программисты будут удивлены, что применение О или NULL в качестве нулевогоуказателя приведет к вызову перегрузки для int, но таким программистам необходимо вни­мательно прочесть раздел 3.2 и читать его до полного просветления в данном вопросе.Д и сп етчериза ция де с кри п торовНи передача lvаluе-ссылки на const, ни передача по значению не предоставляют под­держку прямой передачи.

Если мотивом использования универсальной ссылки являетсяпрямая передача, мы вынуждены использовать универсальную ссылку; у нас просто нетиного выбора. Тем не менее мы не хотим отказываться и от перегрузки. Если мы не отка­зываемся ни от перегрузок, ни от универсальных ссылок, то как же мы сможем избежатьперегрузки для универсальных ссылок?В действительности это не так трудно.

Вызовы перегруженных функций разрешаютсяпутем просмотра всех параметров всех перегрузок, а также всех аргументов в точке вы­зова с последующим выбором функции с наилучшим общим соответствием - с учетомвсех комбинаций "параметр/аргумент". Параметр, являющийся универсальной ссылкой,обычно обеспечивает точное соответствие для всего, что бы ни было передано, но еслиуниверсальная ссылка является частью списка параметров, содержащего другие параме­тры, универсальными ссылками не являющиеся, достаточно плохое соответствие этихпоследних параметров может привести к отказу от вызова такой перегрузки. Эта идея ле­жит в основе подхода диспетчеризации дескрипторов (tag dispatch), а приведенный нижепример позволит лучше понять, о чем идет речь.Применим этот метод к примеру logAndAdd из третьего фрагмента кода раздела 5.4.Чтобы вам не пришлось его искать, повторим его здесь:std : : multiset<std : : string> name s ; / / Глобальная структура данныхtemplate<typename Т>void logAndAdd ( T & & name )11 Делает запись в журнале и11 добавляет name в names5.5.

Знакомство с альтернативами перегрузки для универсальных ссылок191auto nowstd : : chrono : : system_clock: : now ( ) ;log ( now, " logAndAdd" ) ;names . emplace ( std : : forward<T> ( name ) ) ;=Сама по себе эта функция работает отлично, но если мы добавим перегрузку, принима­ющую значение типа int, использующееся для поиска объекта по индексу, то получим про­блемы, описанные в разделе 5.4. Цель данного раздела - их избежать.

Вместо добавленияперегрузки мы реализуем l ogAndAdd заново для делегирования работы двум другим функ­циям: одной - для целочисленных значений, а другой - для всего прочего. Сама функцияlogAndAdd будет принимать все типы аргументов, как целочисленные, так и нет.Эти две функции, выполняющие реальную работу, будут называться logAndAdd impl,т.е. мы воспользуемся перегрузкой. Одна из этих функций будет принимать универсаль­ную ссылку. Так что у нас будет одновременно и перегрузка, и универсальные ссылки.

Нокаждая функция будет принимать и второй параметр, указывающий, является ли пере­даваемый аргумент целочисленным значением. Этот второй параметр и будет средством,избавляющим нас от падений в болото, описанное в разделе 5.4, так как он будет факто­ром, определяющим выбираемую перегрузку.Что вы говорите? "Хватит трепа, переходи к делу"? Да хоть сию секунду! Вот почтикорректная версия обновленной функции logAndAdd:template<typename Т>void logAndAdd (T&& name ){logAndAddimpl ( st d : : forward<T> ( name ) ,std: : is integral<Т> ( ) ) ; / / Не совсем корректно_Эта функция передает свой параметр в logAndAddi mpl и при этом передает также ар­гумент, указывающий, является ли тип параметра (Т) целочисленным.

Как минимумэто то, что она должна делать. То же самое она делает и для целочисленных аргумен­тов, являющихся rvalue. Но, как поясняется в разделе 5.6, если lvаluе-аргумент переда­ется универсальной ссылке name, то выведенный тип для т будет Ivаluе-ссылкой. Такчто если в функцию l ogAndAdd передается lvalue типа i n t , то тип Т будет выведен какint &.

Но это не целочисленный тип - ссылка таковым не является. Это означает, чтоstd : : i s_i n t e g ra l <T> будет иметь ложное значение для любого lvаluе-аргумента, дажеесли этот аргумент на самом деле является целочисленным значением.Понимание данной проблемы равносильно ее решению, поскольку в стандартной би­блиотеке имеется такое средство, как s t d : : remove_refe rence (см. раздел 3.3), котороеделает то, о чем говорит его имя и в чем мы так нуждаемся: удаляет любые квалификато­ры ссылок из типа. Так что верный способ написания l ogAndAdd имеет следующий вид:template<typename Т>void logAndAdd (T&& name )192Глава 5 .

Rvаluе-ссылки, семанти ка перемещений и п рямая передачаlogAndAddimpl (std : : forward<T> ( name ) ,std : : i s integral<typename std: : remove reference<T>: : type_>());Это в определенной мере трюк. (Кстати, в С++ 14 можно сэкономить несколько нажатийклавиш, воспользовавшись вместо выделенного текста st d : : remove r e f e r e nce t <T>.Подробнее об этом рассказывается в разделе 3.3.)После принятия этих мер мы можем перенести наше внимание к вызывае­мой функции, l ogAndAdd i mp l . Имеются две перегрузки, первая из которых приме­н има к любому нецелочисленному типу (т.е. ко всем типам, для которых значениеstd : : i s integra l < t ypename std : : remove_reference<T> : : type> ложно):11 Нецелочисленный аргумент добавляется11 в глобальную структуру данных :template<typename Т>void logAndAddimpl (T&& name , s t d : : fa lse t ype )_{auto nowstd : : chrono : : system_clock : : now ( ) ;l og ( now, " logAndAdd " ) ;names .

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

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

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

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