Главная » Просмотр файлов » Д. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003)

Д. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003) (1160769), страница 29

Файл №1160769 Д. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003) (Д. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003)) 29 страницаД. Вандевурд, Н.М. Джосаттис - Шаблоны C++. Справочник разработчика (2003) (1160769) страница 292019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

Добавим, что если ключевое слово сешр1асе не является необходимым, то его использование запрещено . Нельзя насыщать код квалификаторами б шаблонов "просто так". б На самом деле ю текста стандарта это ие очевидно, но те, кго работал над этой частью стандарта, согласны с данным утверждением. Глава 9. Имена в шаблонах 158 9.3.4. Зависимые имена в объявлениях ибшя Объявления ив1пд могут быть привнесены в имена из двух мест — пространств имен и классов.

Случай пространств имен в данном контексте нас не интересует, поскольку не существует шаблонов пространств имен. Что касается классов, то в действительности обьявления пвхпд привносятся только из базового класса в порожденный. Такие объявления ив1пд в порожденном классе ведут себя как "символические связи" (илн "ярлыки"), направленные из порожденного класса к базовому, обеспечивая таким образом членам порожденного класса доступ к соответствующему имени базового класса, как если бы оно было объявлено в порожденном классе. Краткий пример, не содержащий шаблонов, проиллюстрирует сказанное лучше, чем множество слов. с1авв ВХ ( риЫ1с: уо16 х(1пс); уоЫ й(с)зат сопвк*); И д()> с1авв ВХ : ртхуасе ВХ ( риЬ11с: пвхпд ВХ::Й1 Объявление ив1пд привносит имя й из базового класса ВХ в порожденный класс ЭХ.

В данном случае это имя ассоциировано с двумя разными объявлениями; таким образом ' подчеркивается, что мы имеем дело с механизмом для имен, а не с отдельными объявлениями. Заметим также, что такой вид ияепд-объявления может сделать доступным член класса, который в противном случае был бы недоступен. Базовый класс ВХ (и соответственно его члены) является закрытым по отношению к классу ВХ, за исключением функций ВХ:: й, которые введены в открытом интерфейсе ЭХ и являются, следовательно, доступными для клиентов ВХ. Поскольку механизм ивхпд-объявлений перекрывает использовавшийся ранее механизм объявлений доступа, последний не рекомендован к применению (и в будущих версиях С++ может быть исключен из стандарта). с1аев ВХ : рт1уате ВХ ( ри)з11с~ ВХ::Й; // Синтаксис объявлений доступа.

Не // рекомендован к использованию; взамен // предлагается иехпд ВХ::й Вы уже должны сами представлять проблему, возникающую, когда ивхпдобъявление привносит имя из зависимого класса. Хотя вы и знаете об имени, неизвестно. является ли оно именем типа, шаблона или чем-либо еще. сеюр1атеесурепаве Т> с1авв ВХТ ( риЫ1с: 159 9.3. Синтаксический анализ шаблонов куреней Т Мувсегу; сшар1асе<гурепаше ()> вегас Мад1с; Сешр1асе<сурепаше Т> с1авв )3ХТТ: ргйчаее ВХТ<Т> ( ри)з11с: ивйпд сурепаше ВХТ<Т>::Мувсегу; Мувсегу* р; // Если бы не Гурепаше, зта строка // была бы ошибочна )' Если вы хотите, чтобы зависимое имя было введено с помощью пвйпд-объявления для обозначения типа, то должны явно указать зто путем вставки ключевого слова гурепаше.

Как ни странно, но стандарт С++ не предоставляет аналогичного механизма для того, чтобы пометить такие зависимые имена как шаблоны. Приведенный ниже фрагмент кода иллюстрирует зту проблему. сешр1асе<сурепаше Т> с1авв ВХТМ: ргйчасе ВХТ<Т> ( ри)з11с: ивйпд ВХТ<Т>::Гешр1асе Мадйс; // ОШИБКА: не соответствует стандарту Мадйс<Т>* р11п)с; // СИНТАКСИЧЕСКАЯ ОШИБКА: Мадйс ); // не является известным шаблоном Наиболее вероятно, что зто недосмотр и впоследствии стандарт будет изменен таким образом, чтобы рассмотренная конструкция была корректной. 9.3.5.

АРЬ н явные аргументы шаблонов Рассмотрим приведенный ниже пример. пашеврасе Ш ( с1авв Х ( Гешр1аее<1пс 1> чоЫ ве1есс (Х*); ) той д (М:: Х* хр) ( ве1есг<3>(хр); // ОШИБКА: А))Б не выполняется ) В атом примере логично было бы предположить, что в вызове ве1есг<3> (хр) шаблон ве1есс ( ) отыскивается с помощью А)31.. Однако зто ие так, поскольку компилятор Глава 9. Имена в шабаонах (б0 не может принять решение о том, что кр является аргументом вызова функции, пока не будет решено, что <3> является списком аргументов шаблона И наоборот, невозможно решить, что <3> является списком аргументов шаблона, пока не выяснится, что ве1есс ( ) представляет собой шаблон. Поскольку эту проблему курицы и яйца разрешить невозможно, выражение аналюируется как ( ве1есс < 3 ) > (хр), что не имеет смысла 9.4.

Наследование и шаблоны классов Шаблоны классов могут порождать производные классы или сами быть производными классами. В большинстве случаев особой разницы между сценариями с использованием шаблонов и без них нет; однако есть один важный тонкий момент при порождении шаблона класса из базового класса, обращение к которому выполняется с помощью зависимого имени. Давайте сначала рассмотрим более простой случай независимых базовых классов.

9.4.1. Независимые базовые классы В шаблоне класса независимый базовый класс является классом с завершенным типом, который может быть определен без знания аргументов шаблона. Другими словами, для обозначения этого класса используется независимое имя. сешр1асе<сурепаше Х> с1азв Вазе ( риЫ1с: Тпс Ьавейсе16; Суре6еЕ Тпс Т; с1авв О1: риЫ1с Вазе<вазе<чо16» ( // В действительности зто не шаблон райс: чо16 х() ( Ьавейзе16 = 3; // Обычный доступ к ) // унаследованному члену класса Сешр1аее<сурепаше Т> с1авв В2: риЫТс Вазе<6оиЫе> ( // Независимый базовый класс риЫ1с: чо16 й() ( Ьавехсе16 = 7; // Обычный доступ к ) // унаследованному члену класса Т вегапде // Т здесь — Ваве<6оиЬ1е>::Т, // а не параметр шаблона! 9.4.

Наследование и шаблоны классов 161 ( с)2.векапде = р; // ОШИБКА: несоответствие типов! Такое поведение далеко не интуитивно и требует от разработчика порожденного шаблона внимания по отношению к именам в независимых базовых классах, от которых он порожда- ется, даже когда это порождение является непрямым или имена являются закрьпыми. 9.4.2. Зависимые базовые классы В предыдущем примере базовый класс был полностью определенным и не зависел от параметра шаблона. Это означает, что компилятор С++ может искать независимые имена в тех базовых классах, где видимо определение шаблона.

Альтернатива (не разрешенная стандартом С++) заключается в отсрочке поиска таких имен, пока шаблон не будет инстанцирован. Недостаток этого подхода состоит в том, что до инстанцирования откладывается все сообщения об ошибках. Поэтому в стандарте С++ указано, что поиск независимого имени, присутствующего в шаблоне, происходит немедленно после того, как компилятор столкнется с ним. Рассмотрим с учетом сказанного приведенный ниже пример. тешр1апе<курепаше Т> с1авв О)): рцЬ11с Ваае<Т> ( рцЬ11 с: чоЫ х () ' Ьавейае16 > О; // зависимый базовый класс // (1) проблема.. сешр1асес> // с1ава Ваве<Ьоо1> ( рнЬ11с: епшп ( Ьавесае1б = 42);// Явная специализация (2) Небольшой трюк гоаб д(т))Э<Ьоо1>Н 6) ( б.с (); // (3) 7 Поведение независимых базовых классов в шаблонах очень похоже на поведение базовых классов в обычных нешаблонных классах, однако здесь имеет место некоторая досадная неожиданность: когда поиск неполного имени выполняется в производном шаблоне, независимые базовые классы рассматриваются до списка параметров шаблона Это означает, что в предыдущем примере член класса впкапде шаблона класса )Э2 всегда имеет тип Т, соответствующий Ване<с)опЬ1е>::Т (другими словамн, Тпс).

Например, следующая функция с точки зрения С++ некорректна (при использовании предыдущих объявлений): чоЫ д ())2<1пс*>Ь 62, Тле* р) ( Глава 9. Имена в шаблонах 162 В точке (1) имеется осыпка на независимое имя Ьавей1е1с(, поиск которого следует провести немедленно. Предположим, что оно найдено в шаблоне Вазе и связано с членом класса с типом 1пс в этом классе. Однако после этого компилятор встречает явную специализацию данного класса. Когда это происходит, смысл члена класса Ьавеййе1с( изменяется — при том, что его старый смысл уже использован! Так, при инстанцировании определения РР:: б в точке (3) выясняется, что независимое имя в точке (1) связано с членом класса типа Тпрр преждевременно — в РР<Ьоо1> не существует переменной Ьавей1е1с(, которой можно было бы присвоить новое значение (теперь это элемент перечисления из специализации в точке (2)), так что компилятором будет выдано сообщение об ошибке.

Чтобы обойти эту проблему, стандарт С++ гласит, что поиск независимых имен ие проводится в зависимых базовых классах (однако сам поиск выполняется, как только 7 эти имена встречаются компилятором). Таким образом, соответствующий стандарту С++ компилятор выдаст диагностику в точке (1). Для исправления кода достаточно сделать имя Ьавей1е16 зависимым, поскольку поиск зависимых имен может проводиться только во время иистанцирования шаблона, а к этому моменту точная специализация базового класса, где будет вестись поиск, уже будет известна. Например, в точке (3) компилятор уже будет знать, что базовым по отношению к ВВ<Ьоо1> является класс Ваве<Ьоо1>, явно специализированный программистом.

Сделать имя зависимым можно, например, как показано ниже. // Вариант 1: Еешр1аее<сурепаше Т> с1авн РВ1: рцЬ11с Ване<Т> ( риЬ11с: чойс( б()( сЬ1в->Ьавей1е16 = О; // Поиск отложен Еще один вариант — введение зависимости с помощью полного имени. // Вариант 2: сЕвр1асЕ<курЕПаШЕ Т> с1авв ВР2: риЬ11с Ваве<Т> ( риЬ11с: чойс( й() ( Ване<Т>::ЬавеййеЫ = 0; ) Применение этого варианта требует особой тщательности, поскольку если неполное независимое имя используется для формирования вызова виртуальной функции, то уточнение подавляет механизм виртуального вызова и смысл программы изменяется.

Несмотря на это, существуют ситуации, когда первый вариант нельзя использовать и приходится применять альтернативный. Это часть тах называемого правила двукфазиага иваска, и котором различаются первая фаза, когда определения шаблона встречаются впервые, н вторая фаза, когда происходит инсталлирование шаблона (см. раздел 10.3.1, стр. 170). 9.4. Наследование и шаблоны классов 163 семр1аге<сурепшае Т> с1авв В ( рцЫТс: епша Е (е1 = б, е2 = 28, е3 = 496 ); чйгтпа1 чойс( лего(Е е = е1); чйггпа1 чойс) опе(Ей); сетр1аге<гурепате Т> с1авв )З: рцЬ11с В<Т> ( рцЫТс: чойс) й(] ( сурепке 0<Т>::Е е; // СМв->Е синтаксически некорректно сМв->кето(); // П<Т>::гего(] подавляет виртуальность опе(е)г // опе является зависимым именем в силу // зависимости аргумента функции Заметим, что имя опе в вызове опе (е] зависимо от параметра шаблона просто потому, что тип одного из явно заданных аргументов вылова является зависимым.

Неявно используемые аргументы по умолчанию с типом, который зависит от параметра шаблона, во внимание не принимаются, поскольку компилятор не может их проверить до тех пор, пока не будет проведен поиск, — все та же проблема курицы и яйца. Чтобы избежать таких нюансов, предпочтительно использовать префикс е1п.в-> во всех ситуациях, где это только можно, — даже для нешаблонного кода. Если вы обнаружите, что повторяющиеся квалификаторы загромождают ваш код, можно внести имя из зависимого базового класса в порожденный класс раз и навсегда // Вариант 3: ьетр1аге<сурепате Т> с1авв )З)ЗЗ: рцЬ11с Ваве<Т> ( райс: цвйпд Ваве<Т>::ЬавеНе16; // (1) Теперь зависимое // имя в области видимости чо16 й() ( Ьавеййе1д = Ог ) // (2) Все в порядке Поиск в точке (2) успешен и находит объявление цвйпд в точке (1).

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

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

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

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