Подтвердить что ты не робот

Transform_primary() и collate_byname()

Чтобы дать контекст того, о чем я говорю, следующая программа корректно печатает true при компиляции с помощью clang++/libС++

#include <iostream>
#include <regex>
int main()
{
    std::locale::global(std::locale("en_US.UTF-8"));
    std::wstring str = L"AÀÁÂÃÄÅaàáâãäå";
    std::wregex re(L"[[=a=]]*", std::regex::basic);
    std::cout << std::boolalpha << std::regex_match(str, re) << '\n';
}

однако я не могу полностью понять описание std::regex_traits::transform_primary() в стандарте (с помощью которого обрабатывается [=a=]). Для цитирования 28.7 [re.traits]/7:

если typeid(use_facet<collate<charT> >) == typeid(collate_byname<charT>) и форма ключа сортировки, возвращаемая collate_byname<charT>::transform(first, last), известна и может быть преобразована в основной ключ сортировки, а затем возвращает этот ключ, в противном случае возвращает пустую строку.

В оригинальном предложении объясняется, что стандартный regex_traits::transform_primary() может работать, только если фасет collate в внедренной локали не был заменен пользователем (что единственное способ, которым он может знать, как преобразовать результат collate::transform() в ключ эквивалентности).

Мой вопрос в том, как сравнение typeid в стандарте должно гарантировать это? Означает ли это, что все системные грани, выведенные из локалей с use_facet, имеют _byname как их истинные динамические типы?

4b9b3361

Ответ 1

"Мой вопрос: как сравнение типов в стандарте должно гарантировать это? Имеет ли это значение, что все предоставленные системой грани, выведенные из локалей с помощью use_facet, имеют _byname как их истинные динамические типы?"

чтобы ответить на первую половину вашего вопроса, сравнение типов проверяет это, потому что, если пользователь создал экземпляр шаблона с другим значением для use_facet, сравнение типов не завершится. если typeid соответствует, будет гарантировано, что функция, которая будет отправлена, не будет переопределена пользователем. таким образом, вы получите класс системы collate_byname, и будет вызвано правильное преобразование.

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

Обратите внимание также, что нет никакого переносимого способа реализации transform_primary в терминах std:: locale, так как даже если формат ключа сортировки, возвращаемый std:: collate_byname < > :: transform известен и может быть преобразован в основной ключ сортировки, пользователь все еще может установить свой собственный std:: сопоставить реализацию в используемом объекте locale, и это может используйте любой формат ключа сортировки, который они считают нужным. Член transform_primary поэтому функция более полезна для пользовательских классов признаков и должна выдать исключение, если оно не может быть реализовано для конкретного локали.

это говорит нам, что если для этого типа /typeid есть что-либо, кроме ожидаемого (то есть системного) значения, результаты могут быть непредсказуемыми, поскольку пользователь может предоставить другой формат ключа сортировки., придерживаясь значения, предоставленного системой, тип type для этой грани будет известен, и, таким образом, ключ сортировки будет известен и предсказуем.