Книги
чёрным по белому
Главное меню
Главная О нас Добавить материал Поиск по сайту Карта книг Карта сайта
Книги
Археология Архитектура Бизнес Биология Ветеринария Военная промышленность География Геология Гороскоп Дизайн Журналы Инженерия Информационные ресурсы Искусство История Компьютерная литература Криптология Кулинария Культура Лингвистика Математика Медицина Менеджмент Металлургия Минералогия Музыка Научная литература Нумизматика Образование Охота Педагогика Политика Промышленные производства Психология Путеводители Религия Рыбалка Садоводство Саморазвитие Семиотика Социология Спорт Столярное дело Строительство Техника Туризм Фантастика Физика Футурология Химия Художественная литература Экология Экономика Электроника Энергетика Этика Юриспруденция
Новые книги
Цуканов Б.И. "Время в психике человека" (Медицина)

Суворов С. "Танк Т-64. Первенец танков 2-го поколения " (Военная промышленность)

Нестеров В.А. "Основы проэктирования ракет класса воздух- воздух и авиационных катапульных установок для них" (Военная промышленность)

Фогль Б. "101 вопрос, который задала бы ваша кошка своему ветеринару если бы умела говорить" (Ветеринария)

Яблоков Н.П. "Криминалистика" (Юриспруденция)
Реклама

Эффективное использование STL. Библиотека программиста - Мейерс С.

Мейерс С. Эффективное использование STL. Библиотека программиста — Спб.: Питер , 2002. — 224 c.
ISBN 5-94723-382-7
Скачать (прямая ссылка): effektivnoeispolzovaniestlbibliote2002.djvu
Предыдущая << 1 .. 77 78 79 80 81 82 < 83 > 84 85 86 87 88 89 .. 114 >> Следующая

синтаксисе 2 и 3) при помощи синтаксиса 1.
Принцип работы mem_fun и mem_fun_ref прост, хотя для пущей ясности
желательно рассмотреть объявление одной из этих функций. В
действительности они представляют собой шаблоны функций, причем
существует несколько вариантов mem_fun и mem_fun_ref для разного
количества параметров и наличия-отсутствия константности адаптируемых ими
функций классов. Одного объявления вполне достаточно, чтобы разобраться в
происходящем:
tempiate<typename R, typename C> // Объявление mem_fun для неконстантных
mem_fun_t<R.C> // функций без параметров. С - класс.
mem_fun(R(C: :*pmf)0): // R - тип возвращаемого значения функции,
// на которую ссылается указатель
Функция mem_f un создает указатель pmf на функцию класса и возвращает
объект типа mem_fun_t. Тип представляет собой класс функтора, содержащий
указатель на функцию и функцию operatorO, которая по указателю вызывает
функцию для объекта, переданного operatorO. Например, в следующем
фрагменте:
list<Widget*> lpw:
// См. ранее
Совет 41 163
for_each(1pw.begi n(). 1 pw.end(),
mem_fun(&Widget::test)); // Теперь нормально компилируется
При вызове for_each передается объект типа mem_fun_t, содержащий
указатель на Wi dget:: test. Для каждого указателя Wi dget* в 1 pw
алгоритм for_each "вызывает" объект mem_fun_t с использованием синтаксиса
1, а этот объект непосредственно вызывает Widget:: test для указателя
Widget* с использованием синтаксиса 3.
В целом mem_fun приводит синтаксис 3, необходимый для Widget::test при
использовании с указателем Widget*, к синтаксису 1, используемому
алгоритмом for_ each. По вполне понятным причинам такие классы, как
mem_fun_t, называются адаптерами объектов функций. Наверное, вы уже
догадались, что по аналогии со всем, о чем говорилось ранее, функции
memfunref адаптируют синтаксис 2 к синтаксису 1 и генерируют адаптеры
типа mem_fun_ref_t.
Объекты, создаваемые функциями mem_fun и mem fun ref, не ограничиваются
простой унификацией синтаксиса для компонентов STL. Они (а также объекты,
создаваемые функцией ptr fun) также предоставляют важные определения
типов. Об этих определениях уже было рассказано в совете 40, поэтому я не
стану повторяться. Тем не менее, стоит разобраться, почему конструкция
for_each(vw.begin(),vw.end(),test): // См. ранее, вариант 1.
// Нормально компилируется
компилируется, а следующие конструкции не компилируются:
foi-_each(vw.begin().vw.end().&Widget: :test); //См. ранее, вариант 2.
// Не компилируется.
for_each(lpw.begin() ,lpw.end() ,&Widget: :test): //См. ранее, вариант 3.
//Не компилируется
При первом вызове (вариант 1) передается настоящая функция, поэтому
адаптация синтаксиса вызова для for_each не нужна; алгоритм сам вызовет
ее с правильным синтаксисом. Более того, for each не использует
определения типов, добавляемые функцией ptr_fun, поэтому при передаче
test функция ptr_fun не нужна. С другой стороны, добавленные определения
не повредят, поэтому следующий фрагмент функционально эквивалентен
приведенному выше:
for_each(vw.begin(),vw.end(),ptr_fun(test)): // Компилируется и
работает,
// как вариант 1.
Если вы забываете, когда функция ptr_fun обязательна, а в каких случаях
без нее можно обойтись, лучше используйте ее при всех передачах функций
компонентам STL. STL игнорирует лишние вызовы, и они не отражаются на
быстродействии программы. Возможно, во время чтения вашей программы кто-
нибудь удивленно поднимет брови при виде лишнего вызова ptr_fun.
Насколько это беспокоит вас? Наверное, ответ зависит от природной
мнительности.
Существует и другой подход - использовать ptr_fun в случае крайней
необходимости. Если функция отсутствует там, где необходимы определения
типов, компилятор выдает сообщение об ошибке. Тогда вы возвращаетесь к
программе и включаете в нее пропущенный вызов.
С mem_fun и mem_fun_ref ситуация принципиально иная. Эти функции всегда
должны применяться при передаче функции компонентам STL, поскольку помимо
определения типов (необходимых или нет) они адаптируют синтаксис вызова,
164 Глава б • Функции, функторы и классы функций
который обычно используется для функций класса, к синтаксису, принятому в
STL. Если не использовать эти функции при передаче указателей на функции
класса, программа не будет компилироваться.
Остается лишь разобраться со странными именами адаптеров. Перед нами
самый настоящий пережиток прошлого STL. Когда впервые возникла
необходимость в адаптерах, разработчики STL ориентировались на контейнеры
указателей (с учетом недостатков таких контейнеров, описанных в советах
7,20 и 33, это может показаться странным, но не стоит забывать, что
контейнеры указателей поддерживают полиморфизм, а контейнеры объектов -
нет). Когда понадобился адаптер для функций классов (MEMber FUNctions),
его назвали mem_fun. Только позднее разработчики поняли, что для
контейнеров объектов понадобится другой адаптер, и для этой цели изобрели
имя mem_fun_ref. Конечно, выглядит не слишком элегантно, но... бывает,
Предыдущая << 1 .. 77 78 79 80 81 82 < 83 > 84 85 86 87 88 89 .. 114 >> Следующая