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

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

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

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

И вновь на выручку приходитстандартная библиотека, предоставляя шаблон std : : decay. Тип std : : decay<T > : : t ypeпредставляет собой то же самое, что и тип Т, но из него удалены все ссылки и квалифи­каторы const и volat i le. (Я немного вас обманул, потому что std : : decay, кроме того,превращает массивы и типы функций в указатели (см. раздел 1 . 1 ) , но для наших целейможно считать, что std : : decay ведет себя так, как я описал.) Условие, которое должновыполняться для включения рассматриваемого конструктора, имеет вид' std : : is_same<Person, t ypename std: : decay<T > : : type> : : value1 96Гnава 5. Rvalue-ccыnки, семантика перемещений и прямая передачат.е. Person не совпадает с типом Т, без учета всех ссылок и квалификаторов constи volat i l e.

(Как поясняется в разделе 3.3, ключевое слово t ypename перед std: : decayнеобходимо, поскольку тип s t d : : decay<T> : : t ype зависит от параметра шаблона Т. )Вставка этого условия в шаблон std : : enaЫe_if выше, а также форматирование ре­зультата для того, чтобы проще понять взаимоотношения между частями кода, дает сле­дующее объявление конструктора с прямой передачей класса Person:class Person {puЫic :template<typename Т,typename = typename s t d : : enaЫe if<! std : : is same<Person ,_typename std: : dесау<Т> : : type>: : value> : : type>explicit Person (T&& n ) ;};Если вы никогда ранее не видели ничего подобного, не пугайтесь. Есть причина,по которой я оставил этот метод напоследок.

Если для того, чтобы избежать смешиванияуниверсальных ссылок и перегрузки вы можете использовать один из прочих методов (аэто почти всегда возможно), вы должны это сделать. Тем не менее, если вы привыкнетек функциональному синтаксису и множеству угловых скобок, это не так плохо. Крометого, это позволяет получить поведение, к которому вы стремитесь. С учетом приведен­ного выше объявления построение объекта Person из другого объекта Person (lvalue илиrvalue, с квалификатором const или без него, с квалификатором volat i l e или без него)никогда не вызовет конструктор, принимающий универсальную ссылку.Мы добились успеха? Дело сделано?Пока что нет.

Не спешите праздновать. Раздел 5.4 все еще посылает нам свои приветы.Нам надо заткнуть этот фонтан окончательно.Предположим, что класс, производный от Pe rson, реализует операции копированияи перемещения традиционным способом:class SpecialPerson : puЬlic Person {puЫic :SpecialPerson ( const Specia l Pe rson& rhs ) / / Копирующий// конструктор; вызывает конструкторPerson (rhs)/ / базового класса с прямой передачей !}[".SpecialPe rson ( Special Person& & rhs )// ПеремещающийPerson (std: : move (rhs) ) / / конструктор; вызывает конструктор/ / базового класса с прямой передачей !( ... }};S.S.

Знакомство с аnьтернативами переrрузки дnя универсаnьных ссыпок1 97Это тот же код, который вы видели ранее, в конце предыдущего раздела, вклю­чая комментарии, увы, оставшиеся справедливыми. Копируя или перемещая объектSpecialPerson, мы ожидаем, что части базового класса будут скопированы или переме­щены с помощью копирующего или, соответственно, перемещающего конструктора ба­зового класса. Однако в этих функциях мы передаем объекты Specia lPerson конструк­торам базового класса, а поскольку Spe c i a l Person не совпадает с Person (даже послеприменения s t d : : decay}, конструктор с универсальной ссылкой в базовом классе ока­зывается включенным и без проблем проходит проверку на идеальное совпадение с ар­гументом Speci a l Person.

Это точное соответствие лучше преобразования производногокласса в базовый, необходимого для связывания объекта Spe c i a l Person с параметромPerson в копирующем и перемещающем конструкторах класса Person, так что при име­ющемся коде копирование и перемещение объектов Special Person будет использоватьдля копирования и перемещения частей базового класса конструктор с универсальнойссылкой класса Person! Это чудное ощущение дежавю раздела 5.4 . . .Производный класс просто следует обычным правилам реализации копирующегои перемещающего конструкторов производного класса, поэтому решение этой проблемынаходится в базовом классе и, в частности, в условии, которое контролирует включениеконструктора с универсальной ссылкой класса Person.

Теперь мы понимаем, что надовключать шаблонный конструктор не для любого типа аргумента, отличного от Person,а для любого типа аргумента, отличного как от Person, так и от типа, производногоот P e r s on. Ох уж это наследование!Вас уже не должно удивлять обилие всяческих полезных шаблонов в стандартнойбиблиотеке, так что известие о наличии шаблона, который определяет, является лиодин класс производным от другого, вы должны воспринять с полным спокойстви­ем. Он называется std : : i s_base of. Значение std : : i s_base o f <T l , T2 > : : va lue ис­тинно, если Т2класс, производный от T l .

Пользовательские типы рассматриваютсякак производные от самих себя, так что std : : is _base_o f<T , Т> : : value истинно, еслиТ представляет собой пользовательский тип. (Если Т является встроенным типом,s t d : : is_base_of<T , T> : : va lue ложно.) Это удобно, поскольку мы хотим пересмотретьнаше условие, управляющее отключением конструктора с универсальной ссылкой классаPerson таким образом, чтобы этот конструктор был включен, только если тип Т послеудаления всех ссылок и квалификаторов const и volat i l e не являлся ни типом Person,ни классом, производным от Person. Применение std : : is _base_of вместо std : : is sameдает нам то, что требуется:-_class Person {puЬli c :template<typename Т,typename = typename std : : enaЫe if<! std: : is_Ьase_of<Person,typename std : : decay<T> : : type> : : value198Гnава S . Rvalue-ccыnки, семантика перемещений и прямая передача> : : type>explicit Person (T&& n ) ;);Вот теперь работа завершена.

Вернее, завершена при условии, что мы пишем кодна С++ l l . При использовании С++ 1 4 этот код будет работать, но мы можем использо­вать псевдонимы шаблонов для std : : еnаЫе if и s t d : : decay, чтобы избавиться от хла­ма в виде t ypename и : : t уре, получая несколько более приятный код:class Person {1 1 С++ 1 4puЫ i c :template<typename Т,typenamestd : : enaЬle if t<1 1 Меньше кода здесь! std: : is_base_o f<Person,std : : decay_t<T>11 И здесь> : : value>11 И здесь>=explicit Person (T&& n ) ;);Ладно, я признаю: я соврал.

Мы до сих пор не сделали всю работу. Но мы уже близкик завершению. Соблазнительно близки. Честно!Мы видели, как использовать std : : е nаЫе_ i f для выборочного отключения конструк­тора с универсальной ссылкой класса Person для типов аргументов, которые мы хотимобрабатывать с помощью копирующего и перемещающего конструкторов, но мы еще невидели, как применить его для того, чтобы отличать целочисленные аргументы от не яв­ляющихся таковыми. В конце концов, таковой была наша первоначальная цель; проблеманеоднозначности конструктора была всего лишь неприятностью, подхваченной по дороге.Все, что нам нужно сделать (и на этот раз "все" действительно означает, что это ужевсе), - это ( l ) добавить перегрузку конструктора Person для обработки целочисленныхаргументов и (2) сильнее ограничить шаблонный конструктор так, чтобы он был отклю­чен для таких аргументов.

Положите эти ингредиенты в кастрюлю со всем остальным,что мы уже обсуждали, варите на медленном огне и наслаждайтесь ароматом успеха:class Person {puЫ i c :template<typename Т,typenamestd : : enaЬle i f t<! std : : i s_ba se_of<Person, std: : decay_t<T>> : : value=5.5. Знакомство с альтернативами перегрузки для универсальных ссып ок199&&! std: : is integral<std: : remove reference t<Т>> : : value___>>/ / Конструктор для std : : striпg иexplicit Persoп ( T& & п )пame ( s td : : forward<T> ( п ) ) / / аргументов, приводимь� к/ / std : : striпg{}.. .explicit Person (int idx)name (nameFromidx (idx) )1...11 Конструктор для/ / целочисленных аргументов}11 Копирующий и перемещающий конструкторы и т .

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

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

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

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