На этом шаге мы рассмотрим фацет, используемый для задания правил сортировки.
Фацет collate скрывает различия между правилами сортировки строк в разных локальных контекстах. Например, в немецком языке буква "u с точками" (u умляют) при сортировке строк эквивалентна букве "u" или сочетанию "ue". В других языках эта буква даже не считается буквой и интерпретируется как специальный символ (или не интерпретируется вовсе), но в этих языках действуют иные правила сортировки для некоторых сочетаний символов. Чтобы строки автоматически сортировались в порядке, нужном для пользователя, можно задействовать фацет collate. Функции этого фацета перечислены в таблице 1. Col обозначает специализацию 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>. Для других типов символов пользователи должны писать собственные специализации, в которых могут быть задействованы стандартные специализации.
На следующем шаге мы рассмотрим интернационализацию сообщений.