Шаг 551.
Библиотека STL. Интернационализация. Классификация и преобразования символов. Контекстная сортировка

    На этом шаге мы рассмотрим фацет, используемый для задания правил сортировки.

    Фацет collate скрывает различия между правилами сортировки строк в разных локальных контекстах. Например, в немецком языке буква "u с точками" (u умляют) при сортировке строк эквивалентна букве "u" или сочетанию "ue". В других языках эта буква даже не считается буквой и интерпретируется как специальный символ (или не интерпретируется вовсе), но в этих языках действуют иные правила сортировки для некоторых сочетаний символов. Чтобы строки автоматически сортировались в порядке, нужном для пользователя, можно задействовать фацет collate. Функции этого фацета перечислены в таблице 1. Col обозначает специализацию collate, а в аргументах функций передаются итераторы, используемые для определения строк.

Таблица 1. Функции фацета collate
Выражение Описание
col.compare(beg1, end1, beg2, end2) Возвращаемое значение равно 1, если первая строка больше второй; 0, если строки равны; -1, если первая строка меньше второй
col.transform(beg, end) Возвращает строку, предназначенную для сравнения с другими преобразованными строками
col.hash(beg, end) Возвращает хэш-код строки (типа long)

    Фацет collate представляет собой шаблон класса, получающий в аргументе шаблона тип символов charT. Строки, передаваемые функциям collate, задаются при помощи указателей const charT*. Это несколько неудобно, поскольку нет гарантии, что итераторы, используемые типом basic_string<charT>, также представляют собой указатели. Следовательно, сравнение строк должно производиться фрагментами следующего вида:

locale loc;
string s1, s2;
...
// Получение фацета collate локального контекста locale
const std::collate<charT>&col
 = stdLLuse_facet<std::collate<charT> >(loc);

// Сравнение строк с использованием фацета collate
int result = col.compare(s1.data(), s1.data()+s1.size(),
                         s2.data(), s2.data()+s2.size());
if (result == 0) {
    // s1 и s2 равны
    ...
}

    Такие ограничения связаны с тем, что нужный тип итератора заранее не известен, а определять фацеты для типа указателя и бесконечного числа типов итераторов невозможно.

    Конечно, для сравнения строк в классе locale существует специальная вспомогательная функция:

  int result = loc(s1, s2);

    Однако такое решение работает только с функцией compare(). В стандартной библиотеке C++ не определены вспомогательные функции для двух других функций collate.

    Функция transform() возвращает объект типа basic_string<charT>. Лексикографический порядок строк, возвращаемых функцией transform(), совпадает с порядком следования исходных строк, сортируемых функцией collate(). Функция transform() может использоваться для ускорения работы программы, если одна строка сравнивается с большим количеством других строк. Лексикографический порядок следования строк в этом случае определяется гораздо быстрее, чем при использовании collate(), поскольку национальные правила сортировки могут быть довольно сложными.

    Стандартная библиотека C++ требует обязательной поддержки только двух специализаций - collate<char> и collate<wchar_t>. Для других типов символов пользователи должны писать собственные специализации, в которых могут быть задействованы стандартные специализации.

    На следующем шаге мы рассмотрим интернационализацию сообщений.




Предыдущий шаг Содержание Следующий шаг