Скотт Майерс - Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ
• tr1::mem_fn – синтаксически унифицированный способ адаптации указателей на функции-члены. Как tr1::bind обобщает связыватели bind1st и bind2nd из библиотеки C++98, так и tr1::mem_fn расширяет возможности mem_fn и mem_fn_ref.
• tr1::reference_wrapper – средство, предназначенное для того, чтобы придать ссылкам большее сходство с объектами. В частности, это дает возможность создавать контейнеры, которые ведут себя так, будто содержат ссылки (в действительности контейнер может содержать только объекты или указатели).
• Генератор случайных чисел – средство, намного превосходящее функцию rand, которую C++ унаследовал от стандартной библиотеки C.
• Специальные математические функции, включая полиномы Лагерра, функции Бесселя, полные эллиптические интегралы и многое другое.
• Расширения, совместимые с C99, – набор функций и шаблонов, предназначенных для включения в C++ многих новых средств из библиотеки C99.
Второй набор компонентов TR1 обеспечивает поддержку более изощренной техники программирования с применением шаблонов, включая и метапрограммирование шаблонов (см. правило 48):
• Характеристики типов (type traits) – набор классов для предоставления информации о типах во время компиляции (см. правило 47). По данному типу T классы-характеристики TR1 могут узнать, является ли он встроенным, обладает ли виртуальным деструктором, представляет ли пустой класс (см. правило 39), может ли быть неявно преобразован в некоторый другой тип U и многое другое. Классы-характеристики TR1 также могут также определить правильное выравнивание для данного типа, что очень важно при написании специализированных функций распределения памяти (см. правило 50).
• tr1::result_of – шаблон, позволяющий вывести тип значения, возвращаемого функцией. При написании шаблонов часто важно иметь возможность ссылаться на тип объекта, возвращаемого при вызове функции (шаблона), но этот тип может сложным образом зависеть от типов параметров. tr1::result_of упрощает определение возвращаемого типа значения, возвращаемого функцией… tr1::result_of используется и во многих местах в самой библиотеке TR1.
Несмотря на то что некоторые части TR1 (в частности, tr1::bind и tr1::mem_fn) обобщают ранее существовавшие компоненты, все же TR1 содержит и немало совсем новых возможностей. Ни один из компонентов TR1 не заменяет существующих, поэтому унаследованный код будет продолжать работать.
Отчет TR1 сам по себе – всего лишь документ[4]. Чтобы воспользоваться преимуществами описанной в нем функциональности, необходим доступ к ее реализации. Рано или поздно код будет поставляться вместе с компиляторами, но в 2005 году, когда писалась настоящая книга, вероятно, не все включенное в TR1 вошло в состав имеющейся у вас реализации стандартной библиотеки. К счастью, нужные компоненты можно найти и в других местах: 10 из 14 компонентов TR1 основаны на библиотеках, доступных на сайте Boost (см. правило 55), поэтому это отличный источник TR1-подобной функциональности. Я говорю «TR1-подобной», потому что хотя значительная часть того, что описано в TR1, и базируется на библиотеках Boost, есть некоторые моменты, в которых нынешние версии Boost не вполне соответствуют спецификации TR1. Возможно, когда вы будете читать эту главу, Boost не только будет предоставлять полностью соответствующую TR1 реализацию, но также и те четыре компонента, которые вошли в TR1 независимо.
Если вы предпочитаете применять TR1-подобные библиотеки Boost в качестве временной меры, до тех пор, пока вместе с компиляторами не начнут поставляться собственные реализации TR1, возможно, вам придется применить трюк с пространствами имен. Все компоненты Boost находятся в пространстве имен boost, тогда как компоненты TR1 должны находиться в пространстве std::tr1. Вы можете указать компилятору, чтобы он воспринимал ссылки на пространство std::tr1 как на boost. Вот как это делается:
namespace std {
namespace tr1 = ::boost; // std::tr1 – псевдоним для пространства boost
}
Технически такое поведение считается неопределенным, потому что, как объяснено в правиле 25, запрещается добавлять что-либо в пространство имен std. На практике, однако, возникновение проблем маловероятно. Когда ваш компилятор предоставит собственную реализацию TR1, вам нужно будет только удалить показанный выше псевдоним пространства имен. Код, ссылающийся на std::tr1, останется правильным.
Возможно, наиболее важная часть TR1, которая не базируется на библиотеках Boost, – это хэш-таблицы. Но хэш-таблицы доступны уже много лет из нескольких источников под именами hash_set, hash_multiset, hash_map и hash_ multimap. Есть неплохой шанс, что библиотеки, поставляемые с вашим компилятором, уже содержат эти шаблоны. Если нет, попросите вашу любимую поисковую машину найти эти имена (как и их аналоги в TR1). Наверняка вы найдете несколько источников – как коммерческих, так и открытых.
Что следует помнить• Основная функциональность стандартной библиотеки C++ состоит из STL, потоков iostream и локалей. Также включена стандартная библиотека C99.
• TR1 добавляет поддержку «интеллектуальных» указателей (например, tr1::shared_ptr), обобщенных указателей на функции (tr1::function), кэшированных контейнеров, регулярных выражений и еще 10 компонентов.
• Отчет TR1 сам по себе – всего лишь спецификация. Чтобы воспользоваться преимуществами TR1, понадобится реализация. Одним из источников реализаций компонентов TR1 является проект Boost.
Правило 55: Познакомьтесь с Boost
Вы ищете высококачественные библиотеки с открытым кодом, независимые от платформ и компиляторов? Boost к вашим услугам. Вы хотели бы присоединиться к сообществу амбициозных, талантливых программистов на C++, работающих в русле современных представлений о проектировании и реализации библиотек? Boost к вашим услугам. Хотите одним глазком взглянуть на то, как будет выглядеть C++ в будущем? Boost к вашим услугам.
Проект Boost – это одновременно сообщество разработчиков и набор свободно распространяемых библиотек на C++. Его Web-сайт находится по адресу http://boost.org. Сделайте закладку немедленно!
Существует множество организаций и Web-сайтов, посвященных C++, но Boost обладает двумя уникальными особенностями. Во-первых, он имеет тесные связи с комитетом по стандартизации C++ и способен влиять на его решения. Boost был основан членами этого комитета, и участники одного часто являются также членами другого. Вдобавок к этому Boost всегда провозглашал одной из своих целей служить платформой для тестирования средств, которые могут быть добавлены в Стандарт C++. Одним из результатов таких отношений стало то, что из 14 новых библиотек, предложенных для включения в C++ в отчете TR1 (см. правило 54), более двух третей основаны на работе, проделанной в Boost.
Вторая особенность Boost – процедура приема библиотек. В ее основе лежит публичное обсуждение исходного текста всеми заинтересованными лицами. Если вы хотите предложить библиотеку для Boost, начинайте с отправки письма в список рассылки для разработчиков Boost, чтобы оценить, насколько велик интерес к вашей работе, и инициировать процесс ее предварительного обсуждения. С этого начинается цикл, который на Web-сайте называется «Обсудить, улучшить, подать на рассмотрение снова. Повторять, пока не будет достигнут удовлетворительный результат».
В конечном итоге вы решаете, что ваша библиотека готова для формального внесения на рассмотрение. Менеджер по приемке подтверждает, что она удовлетворяет минимальным требованиям Boost. Например, она должна компилироваться как минимум двумя компиляторами (чтобы продемонстрировать переносимость). Вы также должны подтвердить, что библиотека может быть доступна на приемлемых условиях лицензирования (например, быть бесплатна для коммерческого и некоммерческого использования). Затем ваше предложение предоставляется на официальное рассмотрение сообщества Boost. Во время периода рассмотрения добровольцы изучают представленные вами материалы (исходный код, проектную документацию, пользовательскую документацию и т. п.) и задаются следующими вопросами:
• Насколько хороши проект и реализация?
• Является ли код переносимым между компиляторами и операционными системами?
• Будет ли библиотека использоваться теми, для кого предназначена, то есть людьми, работающими в соответствующей предметной области?
• Является ли документация ясной, полной и точной?
Замечания отправляются в список рассылки Boost, чтобы все могли с ними ознакомиться и прокомментировать. В конце периода обсуждения менеджер по приемке решает, является ли ваша библиотека принятой, условно принятой либо отвергнутой.
Открытое обсуждение позволяет оградить Boost от плохо написанных библиотек, но также помогает авторам уяснить для себя, что входит в понятие проектирования, реализации и документирования кросс-платформенных библиотек промышленного уровня. Для многих библиотек требуется более одного официального рассмотрения, прежде чем их сочтут достойными одобрения.