Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 217
Текст из файла (страница 217)
Часто локализация фиксируется в момент начала работы с системой. Например, можно предположить, что пользователь, выбравший аргентинский испанский в качестве рабочего языка по умолчанию, получит для !оса!е("" ) именно 1оса1е("ез А)!" ) . Беглый взгляд на одну из 1014 Приложение О. Локализация моих систем обнаружил 5 ! мнемоническое имя для контекстов локализации, таких как РОБ1Х, (!е, еп ЮК, еп (13, ея, ея АЛ, !), яг, Иа, р1и 1яо 8859 1. Стандарт РОБИ рекомендует начинать их именем языка (буквами нижнего регистра), за которыми может следовать название страны прописными буквами, после чего может следовать спецификатор кодировки, например, (р УР.(((. Однако этот стандарт не распространяется на все платформы, на некоторых из которых, среди прочего, обнаружил имена 8, п1(, пя, я, (г, я(е и ((а. Стандарт языка С++ не определяет смысла объектов локализации для заданных стран или конкретных естественных языков, что, однако, может стандартизоваться в рамках тех или иных платформ.
Поэтому при обращении к именованным контекстам локализации программисту нужно ознакомиться с соответствующей документацией по его системе (и, возможно, поэкспериментировать). Как правило, нежелательно непосредственно в тексте программы располагать строки с именами локализаций. Это ограничивает переносимость программы и заставляет программиста просматривать весь ее текст при необходимости адаптации программы к новой среде.
Вместо этого лучше динамически считать системную информацию о локализации с помощью !оса(е ( " " ), или предоставить опытному пользователю возможность выбора альтернативной локализации путем ввода соответствующей строки. Например: гоЫ ияег яе( (оса!е(сопя( тыпяа еиеяпоп я(ппд) ( сои( « еиея((оп мг!пя( ?? "Нужна другая локализация? — введите ее имя" Фг(пя я; с(п» я; !оса(е: <81оЬа1 ((оса!е [я.с я(г () ) ) ( д установить указанную пользователем ?? локализацию в качестве глобальной Менее подготовленному пользователю желательно предоставить выбор возможных альтернатив из заранее сформированного списка строк с допустимыми именами.
Программа должна знать, где система хранит сведения о локализации. Если строковый аргумент ссылается на недействительную локализацию, конструктор генерирует исключение гппйзпе еггог (Э !4. )О). Например: гоЫ яе( (ос ((оса1еь 1ос, сопя! сваг* нате) (гу ( !ос = (оса!в (пате) ( ) са(сЬ (гип(1те еггог) ( сепг « "!оса(е з"" «пате « " ч" Ып '( ((е5)пей',п"; ?? ... ) Если контекст локализации именованный, то функция па(пе() вернет его имя, а если неименованный — то яп(п8 (" *" ) . Строку с именем можно использовать для отладки. Например: 0.2. Класс(оса(е 1015 гоЫрпи( (оса1е потев (соле( (оса(еь ту 1ое) ( сои«< "нате о! сиггеи(е!оЬа( !оса(е: " « 1оса!е () .пате () « "~п" т сои(« "пате о!с!авв!с С (оса(е: " « (оса1е::с!авие () .пате () « " тп" ( сот« "пате о1 ' 'ивег в ргеуегге((1оеа!е' ': " «1оса1е ("" ) .пате () « "',п" т сот« "пате ауту 1оса1е: " « ту (ос.пате() « "ти" ( ) Контексты локализации с идентичными именами (отличными от значения по умолчанию з(гупй("*")) считаются совпадающими.
В то же время, операции == или ) = предоставляют более непосредственный способ их сравнения. Вызов 1оеа1е (1ос, "Гоо", еа() создает контекст, подобный 1ос, но фасеты берутся из категории са( контекста 1оса1е("Гоо" ) . Результирующий контекст имеет строку имени лишь в том случае, если она есть у исходного контекста йе. Стандарт не определяет, какова эта строка на самом деле, но предполагается, что она будет отличаться от таковой у контекста йе.
Одно из возможных решений — формирование строки из исходной строки контекста йс плюс имя "Гоо". Например, если у йе строка имени есть "ел Иу", то новый контекст получит строку "еи ЕЧ1(Еоо". Обобщим сведения о строке имени вновь создаваемого контекста следующим образом: Локализации Строка имени !оса1е ( "Гоо" ) "Гоо" 1ос.лате () 1оса1е (1ос) йса(е (йс, "Гоо", са() Новая строка имени, если у (ос есть строка имени; иначе -Илие ("*") !оса1е (1ос, (ос2, са() Новая строка имени, если у 1ос и (ос2 есть строка имени; , иначе — в(г(ле ("*" ) (оса(е(1ос,Гасе() , 'в(г!ие ("*") (ос.еотЫпе((ос2) (аулу ("*") Не существует программных средств, позволяющих для вновь созданного контекста задать строку имени локализации в С-стиле.
Строки имен либо определяются в рамках системы, либо создаются в виде комбинаций таких имен конструкторами объектов 1оса1е. 0.2.1.1. Конструирование новых объектов локализации Новый контекст локализации создается на основе существующего посредством добавления или замены фасетов. В типичном случае это приводит к незначительной модификации исходного контекста. Например: гоЫ1(соле( (оса(еь !ое, сопя( Му топеу (о* тй) гуМу топеу !о определен в ЗР.4.3.! ( (оса!е!ос1 (1оса(е ("РОЯ!Х" ),!ое, !оса!е(: толе(агу); й' топе(агу фоееты из !ос 1оса1е 1ос2 = 1оса1е (1оса1е".:<1авв(с (), пло) ( (У е1овгце плюс пио 1016 Приложение О. Локализация Здесь!ос! является модифицированной копией контекста РОШ, в которую добавляются «денежные» фасеты из 1ос (93.4.3).
Аналогично, 1ос2 является копией контекста в С-стиле, модифицированной для использования Му топеу 1о (5Р.4.3.!). Если аргумент типа Расее' (в нашем случае это Му топеу 1о) равен О, то результируюший контекст будет просто копией аргумента типа 1оса1е. В записи !оса!е (сонет 1оса!е ь х, Гасе!* !) аргумент у должен идентифицировать конкретный тип фасета, просто уасег* не проходит. Например: воЫ а(сопз! 1оса1е::уасе1* тго1, сопз! Му топеу 1о* т(о2) ( 1оса1е!осЗ = 1оса1е (1оса1е:: с1ат(с (), ппо1); 1оса1е 1ос4 = 1оса(е (!оса(е:: с!азз(с (), ппо2); У... ) У егтп не известен тип фосето ~У о)с' тип фасета известен Причина в том, что 1оса1е использует аргумент пасет* для определения типа фасета на этапе компиляции. А именно, реализация 1оса1е использует тип, идентифицируюШий фасет, уасег:: И (5Е).3), для поиска фасета в контексте локализации. Обратите внимание, что конструктор зету(агесс(азв Гасе!> 1оса(е (сота !оса!еь х, Расее«у) ноЫ г (сопвг!оса1еь 1ос, сонм 1оса(еь 1ос2) ( 1оса1е 1осЗ = 1ос.сотМпе<Му топеу 1о> (1ос2) н является единственным языковым механизмом, позволяющим программисту задать фасет, который будет использоваться в объекте локализации.
Именованные контексты локализации предоставляются непосредственно реализациями (91з.2.1). Эти именованные локализации можно извлекать из системной среды. Если программист сможет изучить и понять эти механизмы, он сможет таким способом добавлять новые контексты локализации (5Р.6(11,121).
Набор конструкторов для 1оса1е спроектирован таким образом, чтобы тип каждого фасета становился известен либо путем выведения типа (из параметра Гасе! шаблона), либо благодаря тому, что он достается от другого объекта локализации (и который знает этот тип). Задание аргумента сатеаоеу косвенно определяет тип фасета, потому что в контексте локализации типы фасетов в категориях известны. Это подразумевает, что в классе 1оса1е типы фасетов известны, что позволяет манипулировать ими с минимальными накладными расходами.
Для идентификации типов фасетов класс 1оса1е использует поле 1оса1е::Ы (вь).3). Бывает полезно создать объект локализации, во всем являюшийся копией другого объекта локализации за исключением того, что некоторые его фасеты взяты из третьего контекста локализации. Это реализуется шаблонной функцией-членом созпйпе () . Например: 0.2. Класс!оса(е 1017 Результирующий объект 1осЗ ведет себя как 1ос, только он использует копию Му топеу и (5О.4.3.1) из 1ос2для форматирования ввода/вывода денежных величин.
Если в!ос2нетМу тоиеу Ы, то функция сотйте() сгенерирует исключение гиппте егтог(514.10). Результат работы функции согийпе() не имеет строки имени. 0.2.2. Копирование и сравнение контекстов локализации Объекты 1оса1е копируются при инициализации и в операциях присваивания. Например: // как зщкзпар() гоЫ зиар (!оса!еа х, !оса1еа у) ( 1оса1е Фетр = хг х=у; у = сетр; ) Копия объекта !оса!с считается равной оригиналу, но при этом сама она является отдельным независимым объектом. Например: гоЫ!'(!оса!е* ту 1оса1е) ( 1оса1е 1ос = !оса!е:: с!азз!с () г // "С" 1оса!е (!'(1ос ! = 1оса1е:: с!азз!с ( ) ) ( сегг « "!тр!етепгааоп еггог: зепи' Ьия герон !о гепаог'~п" г ех» (!); Ц(Иос ! = Йоса!е::с!азяс () ) сои! « "по зигрпзе: айЬеззез г!грег',и" Г 1оса(е !оса = 1оса1е (1ос, ту 1оса1е, 1оса1е:: питег1с) г !1"(!ос== 1ос2) ( сои! « "ту питег!с!асе!з аге !Ье загие аз с!азис () 'з питепс!асе!з~п" / // ...
// ... ) Если ту!оса!е имеет отвечающий за числовую пунктуацию фасет ту питрипс!<сваг~, отличный от стандартного пптрипсг<сйаг> из с!азз!с(), то результирующие контексты локализации можно отобразить следующим образом: зозв Приложение (). Локализация со11аге<сйак>: Не существует способа модификации 1оса1е. Вместо этого операции класса!оса1е позволяют создавать новые объекты локализации на базе уже существующих.