Главная » Просмотр файлов » С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс

С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (1114944), страница 85

Файл №1114944 С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (С.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс) 85 страницаС.Б. Липпман, Ж. Лажойе - Язык программирования С++ Вводный курс (1114944) страница 852019-05-08СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

Посколькушаблон min5(T,U) подходит для всех вызовов, для которых подходит min5(T,T), тоодного объявления min5(T,U) вполне достаточно, а объявление min5(T,T) можноудалить. Мы уже говорили в главе 9, что, хотя перегрузка допускается, припроектировании таких функций надо быть внимательным и использовать ее только принеобходимости. Те же соображения применимы и к определению перегруженныхшаблонов.497С++ для начинающихВ некоторых ситуациях неоднозначности при вызове не возникает, хотя по шаблонуможно конкретизировать две разных функции. Если имеются следующие два шаблонадля функции sum(), то предпочтение будет отдано первому даже тогда, когдаtemplate <typename Type>Type sum( Type*, int );template <typename Type>Type sum( Type, int );int ia[1024];// Type == int ; sum<int>( int*, int ); или// Type == int*; sum<int*>( int*, int ); ??конкретизированы могут быть оба:int ival1 = sum<int>( ia, 1024 );Как это ни удивительно, такой вызов не приводит к неоднозначности.

Шаблонконкретизируется из первого определения, так как выбирается наиболееспециализированное определение. Поэтому для аргумента Type принимается int, а неint*.Для того чтобы один шаблон был более специализирован, чем другой, оба они должныиметь одни и те же имя и число параметров, а для параметров разных типов, как, скажем,T* и T в предыдущем примере, параметр в одном шаблоне должен быть способен принятьболее широкое множество фактических аргументов, чем соответствующий параметр вдругом. Например, для шаблона sum(Type*, int) вместо первого формальногопараметра функции разрешается подставлять только фактические аргументы типа“указатель”. В то же время в шаблоне sum(Type, int) первому формальному параметрумогут соответствовать фактические аргументы любого типа.

Первый шаблон sum(Type*,int) допускает более узкое множество аргументов, чем второй, т.е. он болееспециализирован, а следовательно, он и конкретизируется при вызове функции.10.8. Разрешение перегрузки при конкретизации AВ предыдущем разделе мы видели, что шаблон функции может быть перегружен. Крометого, допускается использование одного и того же имени для шаблона и обычной// шаблон функцииtemplate <class Type>Type sum( Type, int ) { /* ... */ }// обычная функция (не шаблон)функции:double sum( double, double );Когда программа обращается к sum(), вызов разрешается либо в пользуконкретизированного экземпляра шаблона, либо в пользу обычной функции – это зависитот того, какая функция лучше соответствует фактическим аргументам.

(Для решениятакой проблемы применяется процесс разрешения перегрузки, описанный в главе 9.)Рассмотрим следующий пример:498С++ для начинающихvoid calc( int ii, double dd ) {// что будет вызвано: конкретизированный экземпляр шаблона// или обычная функция?sum( dd, ii );}Будет ли при обращении к sum(dd,ii) вызвана функция, конкретизированная изшаблона, или обычная функция? Чтобы ответить на этот вопрос, выполним по шагампроцедуру разрешения перегрузки.

Первый шаг заключается в построении множествафункций-кандидатов состоящего из одноименных вызванной функций, объявлениякоторых видны в точке вызова.Если существует шаблон функции и на основе фактических аргументов вызова из негоможет быть конкретизирована функция, то она будет являться кандидатом. Так ли это насамом деле, зависит от результата процесса вывода аргументов шаблона. (Этот процессописан в разделе 10.3.) В предыдущем примере для вывода значения аргумента Typeшаблона используется фактический аргумент функции dd. Тип выведенного аргументаоказывается равным double, и к множеству функций-кандидатов добавляется функцияsum(double, int).

Таким образом, для данного вызова имеются два кандидата:конкретизированная из шаблона функция sum(double, int) и обычная функцияsum(double, double).После того как функции, конкретизированные из шаблона, включены в множествокандидатов, процесс вывода аргументов шаблона продолжается как обычно.Второй шаг процедуры разрешения перегрузки заключается в выборе устоявших функцийиз множества кандидатов.

Напомним, что устоявшей называется функция, для которойсуществуют преобразования типов, приводящие каждый фактический аргумент функциик типу соответствующего формального параметра. (В разделе 9.3 описаныпреобразования типов, применимые к фактическим аргументам функции.) Нужныетрансформации существуют как для конкретизированной функции sum(double, int),так и для обычной функции sum(double, double). Следовательно, обе они являютсяустоявшими.Проведем ранжирование преобразований типов, примененных к фактическим аргументамдля выбора наилучшей из устоявших функций.

В нашем примере оно происходитследующим образом:Для конкретизированной из шаблона функции sum(double, int):•для первого фактического аргумента как сам этот аргумент, так и формальныйпараметр имеют тип double, т.е. мы видим точное соответствие;•для второго фактического аргумента как сам аргумент, так и формальный параметримеют тип int, т.е. снова точное соответствие.Для обычной функции sum(double, double):•для первого фактического аргумента как сам этот аргумент, так и формальныйпараметр имеют тип double – точное соответствие;•для второго фактического аргумента сам этот аргумент имеет тип int, а формальныйпараметр – тип double, т.е. необходимо стандартное преобразование между целым иплавающим типами.499С++ для начинающихЕсли рассматривать только первый аргумент, то обе функции одинаково хороши. Однакодля второго аргумента конкретизированная из шаблона функция лучше.

Поэтомунаиболее подходящей (лучшей из устоявших) считается функция sum(double, int).Функция, конкретизированная из шаблона, включается в множество кандидатов толькотогда, когда процесс вывода аргументов завершается успешно. Неудачное завершение вданном случае не является ошибкой, но кандидатом функция считаться не будет.// шаблон функцииtemplate <class T>Предположим, что шаблон функции sum() объявлен следующим образом:int sum( T*, int ) { ... }Для описанного вызова функции вывод аргументов шаблона будет неудачным, так какфактический аргумент типа double не может соответствовать формальному параметрутипа T*.

Поскольку для данного вызова и данного шаблона конкретизировать функциюневозможно, в множество кандидатов ничего не добавляется, т.е. единственным егоэлементом останется обычная функция sum(double, double). Именно она вызываетсяпри обращении, и ее второй фактический аргумент приводится к типу double.А если вывод аргументов шаблона завершается удачно, но для них есть явнаяспециализация? Тогда именно она, а не функция, конкретизированная из обобщенного// определение шаблона функцииtemplate <class Type> Type sum( Type, int ) { /* ...

*/ }// явная специализация для Type == doubletemplate<> double sum<double>( double,int );// обычная функцияdouble sum( double, double );void manip( int ii, double dd ) {// вызывается явная специализация шаблона sum<double>()sum( dd, ii );шаблона, попадает в множество кандидатов. Например:}При обращении к sum() внутри manip() в процессе вывода аргументов шаблонаобнаруживается, что функция sum(double,int), конкретизированная из обобщенногошаблона, должна быть добавлена к множеству кандидатов.

Но для нее имеется явнаяспециализация, которая и становится кандидатом. На более поздних стадиях анализавыясняется, что эта специализация дает наилучшее соответствие фактическимаргументам вызова, так что разрешение перегрузки завершается в ее пользу.Явные специализации шаблона не включаются в множество кандидатов автоматически.Лишь в том случае, когда вывод аргументов завершается успешно, компилятор будетрассматривать явные специализации данного шаблона:500С++ для начинающих// определение шаблона функцииtemplate <class Type>Type min( Type, Type ) { /* ...

*/ }// явная специализация для Type == doubletemplate<> double min<double>( double, double );void manip( int ii, double dd ) {// ошибка: вывод аргументов шаблона неудачен,// нет функций-кандидатов для данного вызоваmin( dd, ii );}Шаблон функции min() специализирован для аргумента double. Однако этаспециализация не попадает в множество функций-кандидатов. Процесс вывода длявызова min() завершился неудачно, поскольку аргументы шаблона, выведенные для Typeна основе разных фактических аргументов функции, оказались различными: для первогоаргумента выводится тип double, а для второго – int.

Поскольку вывести аргументы неудалось, в множество кандидатов никакая функция не добавляется, и специализацияmin(double, double) игнорируется. Так как других функций-кандидатов нет, вызовсчитается ошибочным.Как отмечалось в разделе 10.6, тип возвращаемого значения и список формальныхпараметров обычной функции может точно соответствовать аналогичным атрибутамфункции, конкретизированной из шаблона.

В следующем примере min(int,int) – этообычная функция, а не специализация шаблона min(), поскольку, как вы, вероятно,// объявление шаблона функцииtemplate <class T>T min( T, T );// обычная функция min(int,int)помните, объявление специализации должно начинаться с template<>:int min( int, int ) { }Вызов может точно соответствовать как обычной функции, так и функции,конкретизированной из шаблона. В следующем примере оба аргумента в min(ai[0],99)имеют тип int.

Для этого вызова есть две устоявших функции: обычная min(int,int) иконкретизированная из шаблона функция с тем же типом возвращаемого значения иint ai[4] = { 22, 33, 44, 55 };int main() {// вызывается обычная функция min( int, int )min( ai[0], 99 );списком параметров:}Однако такой вызов не является неоднозначным. Обычной функции, если онасуществует, всегда отдается предпочтение, поскольку она реализована явно, так чтоперегрузка разрешается в пользу обычной функции min(int,int).501С++ для начинающихЕсли перегрузка разрешилась таким образом, то изменений уже не будет: если позжеобнаружится, что в программе нет определения этой функции, компилятор не станетконкретизировать ее тело из шаблона.

Вместо этого на этапе сборки мы получим ошибку.В следующем примере программа вызывает, но не определяет обычную функцию// шаблон функцииtemplate <class T>T min( T, T ) { ... }// это обычная функция, не определенная в программеint min( int, int );int ai[4] = { 22, 33, 44, 55 };int main() {// ошибка сборки: min( int, int ) не определенаmin( ai[0], 99 );min(int,int), и редактор связей выдает сообщение об ошибке:}Зачем определять обычную функцию, если ее тип возвращаемого значения и списокпараметров соответствуют функции, конкретизированной из шаблона? Вспомните, чтопри вызове конкретизированной функции к ее фактическим аргументам в ходе выводааргументов шаблона можно применять только ограниченное множество преобразований.Если же объявлена обычная функция, то для приведения типов аргументов допустимылюбые трансформации, так как типы формальных параметров обычной функциификсированы.

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

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

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

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