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

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

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

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

22.4. Функторы-классы №1пс1пс[е <зес> с1азз Регзоп с1азз РегзопЯогГСг№сегйоп ( риЬ11с: Ьоо1 орегагог() (Регзоп сопзсй р1, Регзоп сопзгй р2) сопзс ( // Возвращает информацию, меньше ли р1, чем р2 1с[ № () ( все(:: ЗЕС<РЕГЗОП, ЗЫ:: 1ЕЗВ<РЕГЗОП» СО, С1; // Сортировка с помощью оператора < Зье[::ЗЕс<РЕГЗОП, ЗЫ::дГЕагЕГ<РЕГВОП» С2; // Сортировка с помощью оператора > вес[::зес<Регзоп, РегзопЯогсСгЫегйоп> сЗ; // Сортировка по критерию пользователя сО = с1; с1 = с2; // Корректная операция: типы идентичны // ОШИБКА: типы различны 1№ (с1 == сЗ) ( // ОШИБКА: типы различны пашезрасе зсг) ( сешр1асе <Сурепаще Т> с1азз 1езз ( РпЬ11с: Ьоо1 орегасог()(т сопзсй х, т сопвсй у) сопвс 5 Реальная рсализапия этого шаблона несколько отличается от приведенной, поскольку класс 1евв является производным от класса вес::ыпаку еипссзоп.

Более подробную информацию по этому вопросу можно найти и разделе 8.2.4 [18). Во всех трех объявлениях объектов класса зес тип элементов множества и критерий сортировки передаются в виде аргументов шаблонов. Стандартный шаблон зсс[:: 1евз определен таким образом, чтобы возвращать посредством "вызова функции" результат применения оператора <. Приведенная ниже упрощенная реализация этого шаблона поясняет суть дела . 5 450 Глава 22. Объекты-функции и обратные вызовы тесцгп х < уг ) ); ) Подобный вид имеет и шаблон вес): г дтеасет. Поскольку все три критерия сортировки различны, полученные в результате объекты класса век принадлежат разным типам. Поэтому любая попытка присвоения или сравнения двух таких обьектов приводит к ошибке времени компиляции (операнды оператора сравнения должны принадлежать одному и'тому же типу).

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

22.5. Определение функторов В предыдущем примере, демон/р(рирующем применение стандартного класса вес, проиллюстрирован только один способ выбора вида функторов. В данном разделе рассматривается несколько других подходов. 22.5.1. Функторы в роли аргументов типа шаблонов Один из способов передачи функтора — сделать его аргументом типа в шаблоне. Однако тип сам по себе не является функтором, поэтому пользовательская функция или класс должны создавать объект-функтор данного типа.

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

Ниже приведен общий вид шаблона функции, для которой критерий сортировки задается в виде функтора-класса. сещр1асе <сурепаще РО> уо3.6 щу ветс ( .. ) ( // Создание объекта-функции 1й (сщр(х,у)) ( // Сравнение двух величин с // помощью объекта-функции '' 22.5. Определение функторов 45) // Вызов функции с функтором щу веге<не<1::1евв<...» (...) В продемонстрированном подходе выбор кода, с помощью которого проводится сравнение, происходит на этапе компиляции. А поскольку операцию сравнения можно сделать встраиваемой, компиляторы с хорошей оптимизацией способны сгенерировать код, в котором вызовы функтора заменены необходимыми операциями. В идеале оптимизатор должен также обладать способностью избегать выделения памяти для объекта сщр, однако на практике редко встречаются компиляторы, обладающие такими возможностями.

22.5.2. Функторы в роли аргументов функций Другой способ передать функтор — Сделать это с помощью аргументов функции. Зто позволяет создавать необходимый объект-функцию во время работы программы (возможно, для этого придется применить нетривиальный конструктор). По своей эффективности способы передачи функтора в виде аргумента и в виде параметра шаблона почти одинаковы.

Различие состоит в том, что в первом случае обьект-функтор необходимо копировать. Обычно количество затрачиваемых при этом дополнительных ресурсов незначительно, а если обьект-функтор не содержит переменных-членов (часто именно так и бывает), это количество можно свести к нулю. Чтобы лучше понять сформулированное выше утверждение, рассмотрим модифицированную функцию щу вогт.

сетр1асе <куренное Р> чогс) ту вогс (..., Г сщр) ( 1б (сщр(х,у)) ( // Сравнение двух величин с // помощью объекта-функции // Вызов функции с функтором 1ау вогс (..., вМ::1евв<...>() ); В теле функции щу вогс ( ) мы имеем дело с копией передаваемого в нее объекта сщр. Если это значение представляет собой пустой объект класса, нет возможности отличить по состоянию локальный объект-функгор, сконструированный в самой функции, от перелаваемой в зту функцию копии.

Таким образом, вместо того чтобы передавать "пустой Функтор" с помощью аргумента функции, компилятор может просто использовать его лл" разрешения перегрузки, а затем избежать выделения памяти, необходимой 452 Глава 22. Объекты-функции и обратные вызовы для размещения параметра и аргумента. При этом внутри инстанцированной функции в роли функтора может выступать фиктивный локальный объект. Этот метод работает почти всегда, но при условии, что конструктор копирования "пустого функтора" лишен побочных эффектов.

На практике это означает, что любой функтор, в котором определен пользовательский конструктор копирования, не должен оптимизироваться таким образом. Как уже отмечалось, преимущество этого метода спецификации функтора состоит в том, что в аргументе функции можно передавать и указатель на обычную функцию. Ьоо1 ву сгйсегзопО (Т сопвсй х, Т сопвсй у) // Вызов функции с объектом-функцией ву вогг (..., ву сгйгегйоп); Кроме того, многие программисты просто предпочитают синтаксис вызова функции синтаксису, включающему аргументы шаблонов.

22.5.3. Сочетание параметров функции и параметров типа шаблона Путем комбинирования двух описанных выше методов передачи функгоров в функции и классы можно задавать аргументы функции, применяющиеся по умолчанию. севр1асе <Гурепаве Р> чотб ву вогс (..., р свр = Р() ) Тт (свр(х,у) ) ( // сравнение двух величин с // помощью объекта-функции Ьоо1 ву сгз.сегйоп ()(Т сопвсй х, Т сопвсй у) // Вызов функции с передачей функтора в аргументе шаблона ву ноге<вес)::1евв<...» (...); // Вызов функции с передачей функтора в ее аргументе ву вогс(..., вгй:гаева<...>()); // Вызов функции с указателем на функцию, // передаваемом в ее аргументе ву вогс(..., ву сгтгегтоп)з 22.5. Определение функторов 453 Таким образом созданы, например, классы упорядоченных множеств элементов, входящие в состав стандартной библиотеки С++.

при этом критерий сортировки можно передавать во время работы программы в виде аргумента конструктора. с1авв кцпе1шеСшр ( // Передача критерия сортировки на этапе компиляции в виде // аргумента шаблона (с использованием критерия сортировки, // который задается в конструкторе по умолчанию) век<хне,кцпгхшесшр> с1; // Передача критерия сортировки на этапе выполнения в виде // аргумента конструктора вег<хпс,кцпс1шеСшр> с2(кцпсхшеСшр(...))з Более подробную информацию по этому вопросу можно найти в [18].

22.5.4. Функторы в роли не являющихся типами аргументов шаблонов Еще один из возможных способов передачи функторов — через не являющиеся ти- пами аргументы шаблонов. Как уже упоминалось в разделах 4.3, стр. б2, и 8.3.3, стр. 133, объект функтора-класса (и вообще объект класса) не может выступать в роли не являю- щегося типом аргумента шаблона. Например, приведенный ниже код неверен. с1авв МуСг1сегхоп ( рцЬ11с: Ьоо1 орегасог() (ЯошеТуре соплей, ЯошеТуре соплей) сопле; гешр1аге <мусг1гегхоп Р> // ОшиБк)(: мусгзсег1оп// это класс Та шу вогс(...): Однако в роли не являющегося типом аргумента можно использовать указатель или ссылку на класс.

Это может привести к попытке создания кода, пример которого приведен ниже. с1авв МуСгтсег1оп ( рцЬ11с: ч1ггца1 Ьоо1 орегагог О (яошеТуре соплей, ЯошеТуре соплей) сопле с1авв Ьевятпап : рцвхйс МуСг1еегхоп ( Глава 22. Объекты-функции и обратные вызовы 454 риЬ11с: уйггиа1 Ьоо1 орегасог() (ЯощеЯЗре соплей, ЯощеТуре сопвсй) сопев; Сетр1аге<МуСгйсегйопй Р> уо3.с) вогс (...); ЬеввТЬап огс)ег; вогг<огс)ег> (...) // ОШИБКА: требуется привести // производный тип к базовому вогс<(МуСгйсегйопй)огдег> (...)г // ОШИБКА: аргумент, не являющийся // параметром типа, не должен быть // ссылкой с использованием // приведения типа.

Идея рассмотренного примера заключается в том, чтобы указать интерфейс критерия сортировки в абстрактном баювом классе, а затем использовать этот класс в качестве параметра шаблона В идеальном мире затем можно было бы просто создать производные классы (например, класс ЬевзТЬеп), с помощью которых был бы доступен интерфейс базового класса (мусгйсегйоп). к сожалению, в с++ такой подход недопустим, поскольку тип не являющихся типом аргументов шаблонов, содержащих ссылки или указатели, должен точно соответствовать типу параметра. Неявное преобразование производного типа к базовому не выполняется, а явное преобразование делает аргумент неприемлемым.

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

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

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

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

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