"Эффективное использование STL" - читать интересную книгу автора (Мейерс Скотт)

Благодарности

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

Другим выдающимся источником информации были конференции Usenet; посвященные языку С++, особенно comp.lang.c++.moderated («clcm»), comp.std.c++ и microsoft.public.vc.stl. Свыше десяти лет участники этих и других конференций отвечали на мои вопросы и ставили задачи, над которыми мне приходилось думать. Я глубоко благодарен сообществу Usenet за помощь в работе над этой книгой и моими предыдущими публикациями по С++.

Мое понимание STL формировалось под влиянием ряда публикаций, самые важные из которых перечислены в конце книги. Особенно много полезного я почерпнул из труда Джосаттиса «The С++ Standard Library» [3].

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

В совете 1 замечание о том, что узловые контейнеры обеспечивают лучшую поддержку транзакционной семантики, позаимствовано из раздела 5.11.2 «The С++ Standard Library» [3]. Пример использования typedef при изменении типа распределителя памяти из совета 2 был предложен Марком Роджерсом. Совет 5 вдохновлен статьeй Ривса (Reeves) «STL Gotchas» [17]. В основу совета 8 заложен совет 37 книги Саттера «Exceptional С++» [8], а Кевлин Хенни (Kevlin Henney) предоставил важную информацию о проблемах, возникающих при использовании контейнеров auto_ptr. В конференциях Usenet Мэтт Остерн (Matt Austem) предоставил примеры использования распределителей памяти, включенные мной в совет 11. Совет 12 основан на материалах сайта SGI STL [21], посвященных потоковой безопасности. Информация о подсчете ссылок в многопоточной среде из совета 13 почерпнута из статьи Саттера [20]. Идея совета 15 была подсказана статьей Ривса «Using Standard string in the Real World, Part 2» [18]. Методика непосредственной записи данных в vector, продемонстрированная в совете 16, была предложена Марком Роджерсом. В совет 17 была включена информация из Usenet, авторы — Симел Наран (Siemel Naran) и Карл Баррон (Carl Barron). Совет 18 был позаимствован из статьи Саттера «When Is a Container Not a Container?» [12]. Для совета 20 Марк Роджерс предложил идею преобразования указателя в объект посредством разыменования, а Скотт Левандовски (Scott Lewandowski) разработал представленную версию DereferenceLess. Совет 21 основан на сообщении Дуга Харрисона (Doug Harrison) в конференцию microsoft.public.vc.stl, но решение о том, чтобы ограничить рамки этого совета проблемой равенства, принял я сам. Совет 22 основан на статье Саттера «Standard Library News: sets and maps» [13]. Совет 23 был подсказан статьей Остерна «Why You Shouldn't Use set — and What to Use Instead» [15]; Дэвид Смоллберг (David Smallberg) усовершенствовал мою реализацию DataCompare. Описание хэшированных контейнеров Dinkumware основано на статье Плаугера (Plauger) «Hash Tables» [16]. Марк Роджерс не согласен с выводами совета 26, но первоначально этот совет был подсказан его замечанием относительно того, что некоторые функции контейнеров принимают только аргументы типа iterator. Работа над советом 29 вдохновлялась дискуссиями в Usenet с участием Мэтта Остерна и Джеймса Канце (James Kanze); на меня также повлияла статья Клауса Крефта (Klaus Kreft) и Анжелики Лангер (Angelika Langer) «А Sophisticated Implementation of User-Defined Inserters and Extractors» [25]. Совет 30 основан на материалак раздела 5.4.2 книги Джосаттиса «The С++ Standard Library» [3]. В совете 31 Марко Далла Гасперина (Marco Dalla Gasperina) предложил пример использования nth_element для вычисления медианы, а использование этого алгоритма для поиска процентилей взято прямо из раздела 18.7.1 книги Страуструпа (Stroustrup) «The С++ Programming Language*. Совет 32 был вдохновлен материалами раздела 5.6.1 книги Джосаттиса «The С++ Standard Library*. Совет 35 появился под влиянием статьи Остерна «How to Do Case-Insensitive String Comparison» [11], а сообщения Джеймса Канце и Джона Потте-ра (John Potter) помогли мне лучше разобраться в сути происходящего. Реализация copy_if, приведенная в совете 36, позаимствована из раздела 18.6.1 книги Страуструпа «The С++ Programming Language» [7]. В основу совета 39 заложены публикации Джосаттиса, который впервые упомянул о «предикатах с состоянием» в своей книге «The С++ Standard Library» [3] и в статье «Predicates vs. Function Objects» [14]. В своей книге я использую его пример и рекомевдую предложенное им решение, хотя термин «чистая функция» принадлежит мне. В совете 41 Мeтт Остерн подтвердил мои подозрения относительно происхождения имен mem_fun и mem_fun_ref. Совет 42 берет свое начало из лекции, прочитанной мне Марком Роджерсом, когда я нарушил рекомендацию этого совета. Марку Роджерсу также принадлежит приведенное в совете 44 замечание о том, что при внешнем поиске в контейнерах map и multimap анализируются оба компонента пары, тогда как при поиске функциями контейнера учитывается только первый компонент (ключ). В совете 45 использована информация от разных участников clem, среди которых Джон Поттер, Марсин Касперски (Marcin Kasperski), Pete Becker (Пит Бекер), Деннис Йель (Dennis Yelle) и Дэвид Абрахаме (David Abrahams). Дэвид Смолл-берг подсказал мне идею применения equal_range для поиска на базе эквивалентности и подсчета результатов в сортированных последовательных контейнерах. Андрей Александреску (Andrei Alexandrescu) помог разобраться в условиях возникновения проблемы «ссылки на ссылку», упоминаемой в совете 50; приведенный в книге пример основан на аналогичном примере Марка Роджерса, взятом с сайта Boost [22].

Разумеется, за материал приложения А следует поблагодарить Мэтта Остерна. Мэтт не только разрешил включить статью в книгу, но и отредактировал ее, чтобы она стала еще лучше оригинала.

Изданию хорошей технической книги всегда предшествует тщательная подготовка. Моей книге повезло — ее просмотрела целая группа выдающихся специалистов. Брайан Керниган (Brian Kerninghan) и Клифф Грин (Cliff Green) прокомментировали ранние наброски, а полную версию книги просматривали Дуг Харрисон, Брайан Керниган, Тим Джонсон (Tim Johnson), Фрэнсис Глассборо (Francis Glassborough), Андрей Александреску, Дэвид Смоллберг, Аарон Кэмпбел (Aaron Campbell), Джаред Мэннинг (Jared Manning), Херб Саттер, Стивен Дью-херст (Stephen Dewhurst), Мэтт Остерн, Гиллмер Дердж (Gillmer Derge), Аарон Мур (Aaron Moore), Томас Бекер (Thomas Becker), Виктор Вон (Victor Von) и, конечно, Марк Роджерс. Редактура была выполнена Катриной Эвери (Katrina Avery).

В процессе подготовки книги очень трудно найти хорошего технического редактора. Я благодарен Джону Поттеру за то, что он познакомил меня с Джаредом Мэннингом и Аароном Кэмпбеллом.

Херб Саттер любезно согласился помочь мне откомпиировать и запустить некоторые тестовые программы STL в бета-версии Microsoft Visual Studio .NET, а Леор Золман (Leor Zolman) взял на себя геркулесов труд по тестированию всего кода в книге. Конечно, все оставшиеся ошибки находятся исключительно на моей ответственности.

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

Печатный вариант настоящей книги лучше предыдущих, поскольку внимательные читатели — Джон Уэбб (John Webb), Майкл Хокинс (Michael Hawkins), Дерек Прайс (Derek Price) и Джим Шеллер (Jim Scheller) — указали на некоторые недостатки. Я благодарен им за помощь по улучшению «Effective STL».

Среди моих коллег в издательстве Addison-Wesley были Джон Уэйт Qohn Wait), редактор, а ныне вице-президент, его заместители Алисия Кэри (Alicia Carey) и Сюзанна Бузард (Susannah Buzard), координатор проекта Джон Фуллер (John Fuller), художник Карин Хансен (Karin Hansen), технический гуру Джейсон Джонс (Jason Jones), особенно хорошо разбирающийся в продуктах Adobe, их начальник Марти Рабиновиц (Marty Rabinowitz), а также Курт Джонсон (Curt Johnson), Чанда Лири-Куту (Chanda Leary-Coutu) и Робин Брюс (Robin Bruce) — специалисты по маркетингу, но вполне нормальные люди.

Эбби Стейли (Abby Staley) сделала мои воскресные обеды привычным, но приятным делом.

Как и во время работы над предыдущими шестью книгами и одним компакт-диском, моя жена Нэнси терпеливо сносила мою хроническую занятость и предлагала свою помощь и поддержку именно тогда, когда я в них больше всего нуждался. Она постоянно напоминала мне, что в жизни есть вещи получше С++ и программ.

Остается упомянуть нашу собаку Персефону. В день, когда я пишу эти строки, ей исполняется шесть лет. Сегодня мы с Нэнси и Персефоной отправимся в «Бас-кин-Роббинс». Как обычно, Персефоне достанется один шарик ванильного мороженого в вафельном стаканчике.