• Matt Austern, «The Standard Librarian: Bitsets and Bit Vectors?», форум экспертов C/C++ Users Journal (сетевое дополнение к журналу), май 2001 г.,В статье описаны контейнеры bitset
, которые сравниваются с vector
, — эти темы кратко рассматриваются в совете 18.
Ошибки и опечатки
• Список ошибок и опечаток в книге «Effective C++»: http://www.aristeia.com/BookErrata/ec++2e-errata.html.
[28] Список ошибок и опечаток в книге «More Effective C++»: http://www.aristeia.com/BookErrata/mec++-errata.html.
• Список ошибок и опечаток на компакт-диске «Effective C++»:aristeia.com/BookErrata/cd1e-errata.html.
[29] Обновления «More Effective C++», относящиеся к auto_ptr
: http://www.awl.com/cseng/titles/0-201-63371-X/auto_ptr.html.
Локальные контексты
В совете 35 приведена реализация сравнения строк без учета регистра символов с применением алгоритмов mismatch и lexicographical_compare, но в нем также указано, что полноценное решение должно учитывать локальный контекст. Книга посвящена STL, а не вопросам интернационализации, поэтому локальным контекстам в ней не нашлось места. Тем не менее, Мэтт Остерн, автор книги «Generic Programming and the STL» [4], посвятил этой теме статью в майском номере журнала «C++ Report» [11]. Текст этой статьи приведен в настоящем приложении. Я благодарен Мэтту и фирме 101communications за то, что они разрешили мне это сделать.
Сравнение строк без учета регистра символов
Если вам когда-либо доводилось писать программы, в которых используются строки (а кому, спрашивается, не доводилось?), скорее всего, вы встречались с типичной ситуацией — две строки, различающиеся только регистром символов, должны были интерпретироваться как равные. В этих случаях требовалось, чтобы операции сравнения — проверка равенства, больше-меньше, выделение подстрок, сортировка — игнорировали регистр символов. Программисты очень часто спрашивают, как организовать подобные операции средствами стандартной библиотеки C++. На этот вопрос существует огромное количество ответов, многие из которых неверны.
Прежде всего необходимо избавиться от мысли о написании класса, сравнивающего строки без учета регистра. Да, с технической точки зрения это более или менее возможно. Тип std::string
стандартной библиотеки в действительности является синонимом для типа std::basic_string
. Операции сравнения определяются вторым параметром; передавая второй параметр с переопределенными операциями «равно» и «меньше», можно специализировать basic_string
таким образом, что операции <
и =
будут игнорировать регистр символов. Такое решение возможно, но игра не стоит свеч.
std::basic_istream
и std::basic_ostream
) специализируются по двум начальным параметрам std::basic_string
(а std::ostream
всего лишь является синонимом для std::basic_ostream
). Параметры характеристик (traits
) должны совпадать. Если вы используете строки типа std::basic_string
, то для вывода строк должен использоваться тип std::basic_ostream
. Стандартные потоки cin
и cout
для этой цели не подойдут.
char_traits
, как и все классы характеристик[5], прост, компактен и не содержит информации состояния. Как будет показано ниже, правильная реализация сравнений без учета регистра не отвечает ни одному из этих критериев.
basic_string
будут игнорировать регистр, это никак не отразится на использовании внешних обобщенных алгоритмов, таких как std::search
и std::find_end
. Кроме того, такое решение перестает работать, если по соображениям эффективности перейти от контейнера объектов basic_string
к таблице строк.