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

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

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

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

22.5.5. Инкапсуляция указателей на функции Предположим, есть схема, в которой используются функторы наподобие критериев сортировки из предыдущих разделов. Допустим также, что в нашем распоряжении есть несколько функций из старых (не шаблонных) библиотек и мы хотели бы использовать их в роли таких функторов. Чтобы решить данную проблему, можно просто обернуть вызов функции в класс. с1авв СгйсегйопХгаррег ( риЬ11с: Ьоо1 орегасог ( ) (...

) ( гесигп ыгаррес) Еипсез'.оп(...); ) 22.5. Определение функторов 455 В приведенном фрагменте кода ыгарреб Еипссйоп (] — зто имеющаяся в нашем распоряжении функция, которая будет использована в роли функтора. Часто такую интеграцию уже существующих функций в классы-функторы приходится выполнять неоднократно, позтому удобно опредешпь шаблон, упрощающий зту задачу. Гешр1аге<1пг (*РР)() > с1азв Рцпсг1опКесцгп1пд1псМгаррег ( ри]>11с: 1пс орегасог().

() ( геецгп РР(); ) ); Ниже приведен завершенный пример. // Ецпсгогв/№цпсмгар.срр №1пс1ибе <чессог> №1пс1цс]е <1овсгешл> №1пс1цс]е <свес]11]з> // Построение оболочки для указателей // на функции в виде объектов-функций Сешр1аге<1пе (*РР) ! ) > с1авв Рцпсе1опКегцгп1пд1пСИгаррег рц]з11с: 1пс орегасог() () ( геецгп РР(); // Пример функции, которая берется в оболочку 1пс гапс[ош 1пс() ( гесцгп згс]::галс](); // Вызов стандартной функции С // Клиент, в котором тип функций-объектов используется // в качестве параметра шаблона Сешр1асе <сурепаше РО> чоЫ 1п1с№а11ке (зсс]::чессог<1пс>а со11) ( РО Ео; // Создание объекта-функции аког(все]::чессог<1пс>::з1ке суре 1=0; < со11.з1ке(); ++1] ( со11[1] = 1о(]; // Вызов функции для // объекта-функции Глава 22. Объекты-функции и обратные вызовы 456 1пс щафп ( ) ( // Создание вектора с 10 элементами вЫ::чесгог<1пг> ч(10); // Инициализация значений с помощью функции в оболочке 1п1г1а11зе<рцпсс1опцегцгп1пд1пгу(гаррег<гапс)ощ 1пг» (ч) // Вывод элементов бог ( вМ:: чесцог<1пг>:: з1ае гуре 1=0; 1<ч.

вфзе (); ++1) ( зМ::соцс « "со11[" «з. « "]: " «ч(1] « вес):: епс)1; Выражение Рцпсг1опцесцгп1пд1п~Жгаррег<гапдощ 1пс> используется при вызове функции 1пфг1а11ке ( ) и служит оболочкой для указателя на функцию галс)ощ 1пг, позволяющей передавать его как параметр типа шаблона Обратите внимание, что в этот шаблон невозможно передать указатель на функцию со связыванием С, например выражение 1п1г1а11зе<Рцпсг1опКесцгп1пд1пс(вгаррег<зЫ:: галс)» (ч) может не сработать, поскольку функция всд:: галс) () входит в состав стандартной библиотеки С (и поэтому может иметь связывание Сь). Чтобы избежать этой проблемы, можно переименовать тип указателей на функции, чтобы у него был нужный тип связывания.

// Тип указателей на функции со связыванием С ехсегп "С" сурес)еб 1пг (*с 1пв РР)(); // Построение оболочки для указателей // на функции в виде объектов-функций Гещр1асе<С 1пс РР РР> с1азв Рцпсс1опКеццгп1пд?псХгаррег ( рцЫ1с: 1пг орегагог() () ( гецшп РР(); ) ); Возможно, здесь еше раз следует подчеркнуть, что шаблоны соответствуют механиз му, работающему на этапе компиляции. Это означает, что компилятору известно, какое 6 Во многих реализациях функции, входящие в стандартную библиотеку С, обладают сказыва. наем С, однако возможна такая реализация С++, которая цредосгавнт эткм функциям свяэывавцс Сн. Поэтому коррекпюсть этого примера зависит от используемой реализации языка.

457 22.6. Самотестирование значение следует подставить вместо обычного параметра РР шаблона Рппсгзопкеспгпзп91пснгаррег. Благодаря этому в большинстве реализаций С++ вызовы, которые на первый взгляд выглядят как косвенные, преобразуются в прямые вызовы. Если же функция встраиваемая и ее определение видимо в том месте, где вызывается функтор, логично ожидать, что компилятор сгенерирует встраиваемый код. 22.6. Самотестирование В контексте программирования термин самотестирование ((щговрес1(оп) означает способность программы проверять свою работу.

Например, в главе 15, "Классы свойств и стратегий", были разработаны шаблоны, которые могут проводить проверку типа. Что касается функторов, то для них часто полезно иметь возможность определять количество параметров и возвращаемый ими тип (илн, скажем, тип и-го параметра функтора). Встречаются функции, дпя которых самотестирование организовать не так просто.

Например, как создать функцию, определяющую тип второго параметра приведенного ниже функтора? с1анв Япрегрцпс ( рпЫзс: чоЫ орегасог() (зпг, с)таг**); В некоторых компиляторах С++ есть специальные функции с именем суреог (), которые определяют тип передаваемых в них выражений, не вычисляя при этом самих выражений (они очень похожи на оператор вйаеог).

Сформулированная проблема во многих случаях решается с помощью подобного оператора, хотя и не всегда тривиальным образом. Концепция функций, подобных суреой (), обсуждается в разделе 13.8, стр. 241. Альтернативой использованию таких функций является разработка функторной конструкции, в которой с помощью функторов создается некоторая дополнительная информация, позволяющая осуществлять определенное самотестирование. 22.6.1. Анализ типа функтора В состав конструкции, которую мы собираемся создать, будут входить только функ- торы-классы, способные обеспечить получение следующей информации: ° количество параметров функтора (в виде константы ыпмРагавв, являющейся перечислением-членом); ° тнп каждого параметра (с помощью определений Сурес)ей, являющихся членом класса, — Рагам1Т, Рагаю2Т, РагамЗТ,...); 7 Чтобы ослабить это ограничение, мы также разработаем инструмент лпя инкапсуляции в разрабатываемую ко" струкцню указателей на функция.

Глава 22. Объекты-функции и обратные вызовы 458 ° тип, возвращаемый функгором (с помощью определения сурес)ег, являющегося членом класса, — кесигпТ). Например, таким образом можно переделать приведенный выше класс Регвопяоггсгтгегйоп. о1авв РегеопЯогесгйеегйоп ( риЬ11о: епиш ( БпшРагашв = 2 )г сурес)ег Ьоо1 йесигпТ; Сурес)ей Регвоп сопвгй Рагаш1Тг Сурес)ег Регвоп сопвса Рагаш2Т; Ьоо1 орегасог() (Регвоп сопвса р1, Регвоп сопвга р2) оопвс ( // Возвращает сгие, если р1 меньше р2 Упомянутых выше соглашений для нас достаточно.

Они позволят разрабатывать шаблоны для создания новых функторов на основе существующих. Есть и другие свойства функторов, которые можно представить подобным образом. Например, можно было бы закодировать информацию о том, что функтор не обладает никакими побочными действиями; ее можно использовать для оптимизации определенных шаблонов. Подобные функторы иногда называют чистыми функторами (рнге Гнпсгог).

Порой бывает полезно организовать проверку этого свойства на этапе компиляции: например, критерий сортировки, как правило, должен быть именно таким; в противном случае результат операции сортировки может оказаться не имеющим смысла. 22.6.2. Доступ к типам параметров Функтор может иметь произвольное количество параметров.

Если придерживаться соглашений, сформулированных в предыдущем разделе, то несложно получить доступ, скажем, к типу восьмого параметра РагашйТ. Однако, работая с шаблонами, полезно позаботиться об обеспечении максимальной гибкости. Как же в данном случае написать функцию, возвращающую тип )У-го параметра для функтора данного типа? Одна из возможностей состоит в использовании частичных специализаций такого шаблона. сещр1асе<сурепаше Рипсгогтуре, Тпс и> с1авв Рипссограгашг 8 По краинси мере в значительной степени. допустимы вскоторыс побочные эффекгы, связан. иыс с кэшированием я журнальными записями, однако лишь я той степени, в которой сяи яс влияют яа возвращаемое функтсром значение.

22.6. Самотестирование 459 При этом можно создать частичные специализации для каждого значения Ы, изменяющегося от единицы до некоторого довольно большого значения (скажем, до 20— ведь у функторов редко бывает более 20 параметров). В каждой частичной специализации может быть определен член Туре, в котором содержится информация о типе соответствующего параметра. При таком подходе возникает одна трудность: непонятно, какой тип должен быть результатом выражения РипссогРагаш<Р,И>::Туре, если значение Ы превышает количество параметров функтора Р. Одна из возможностей — позволить в этой ситуации генерироваться ошибке компиляции. Несмотря на то что это легко организовать, пользы от такой функции Рипсгуопрагаш будет меньше, чем могло бы быть. Еще одна возможность — возвращать в подобных случаях тип чоус(.

Недостаток такого подхода в том, что тип чоус( обладает некоторыми досадными ограничениями. Например, он не может выступать в роли типа параметра функции, и на этот тип невозможно создать ссылку. Поэтому отдадим предпочтение третьей возможности: воспользуемся типом, являющимся закрытым членом класса. Обьекты такого типа создать нелегко, а нх применение связано с некоторыми синтаксическими ограничениями. Ниже приведен код, в котором реализована сформулированная идея. УУ йипсгогз/йппсеограгаш1.Ьрр яупс1пс(е "1йсЬепе1зе.)зрр" Селзр1аге <Сурепаше Р, 1пе Ь(> с1азз УзедРипссогРагаш; сешр1аге <сурепке Р, Тпе М> с1азз РцпсеогРагаш [ ргучасе: с1азз ~Лпизес( ( ргйчасе: с1азз Ргйзгасе риЫ1с: Еурес(ей Ргйзгасе Туре; ); риЫ1с: сурес1ей сурепазае 1ЙТЬепЕ1зе<Р::Мшарагавз>=Ы, агнес(РипссогРагаш<Р, Н>, Упизес1>: г Кези1СТ:: Туре Сетр1аге <Сурепазае Р> с1азз УзейРипсгограгзза<Р, 1> ( рпЫьс: Сурес(ей Еурепаше Р:: Рагаза1Т Туре; ); Глава 22.

Объекты-функции и обратные вызовы 460 С шаблоном 1тТ)зепЕ1ве можно ознакомиться в разделе 15.2.4, стр. 298. Обратите внимание, что в коде введен вспомогательный шаблон плес)Рипстограгам — именнО тот, который должен быль специализирован с конкретными значениями и. Это удобно сделать с помощью макроса. // Типстогв/Типстотрагам2.)зрр йс)етзпе РипстограгамЯрес(Ы) севр1ате<турепаме Р> с1аяв Овес)Рипстотрагам<Р, Н> ( риЬ11с: туре<)ес турепаме Р::Рагамйййййт Туре; // РипстограгащЯрес(2); РипстотрагамЯрес(З); // РипстограгамЯрес(20) йипс)ей РипссогратащЯрес 22.6.3. Инкапсуляция указателей на функции Требование поддержки функторным типом определенного самотестирования в форме членов-суре<)ей исключает использование указателей на функции в этой схеме.

Как уже отмечалось, это ограничение можно обойти путем инкапсуляции указателей на функции. Разработаем небольшой программный инструмент, позволяющий инкапсулировать функции, число параметров в которых не больше двух (большее количество параметров обрабатывается аналогично, однако для ясности изложения рассмотрим пример с двумя параметрами). Здесь описывается случай функций со связыванием С++; связывание С обрабатывается аналогично. Представленное решение состоит из двух компонентов: шаблона класса Рипсттопртг, экземпляры которого являются типами-функторами, инкапсулирующими указатель на функцию, и перегруженного шаблона функции гипс ртг(), получающей указатель на функцию и возвращающей соответствующий нашим требованиям функтор.

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

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

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

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