Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 219
Текст из файла (страница 219)
То есть если строка ввода не является допустимым значением Беаяоп в выбранной локализации, поток устанавливается в состояние/а!! (ошибочное состояние). Гслн допустимы исключения, то подразумевается, что сгенерируется исключение ьоя Ьаяе::/а!!иге Я 21.3.6). Вот тривиальная тестовая программа: т! та!и() // тривиальны тест Беаяоп х; // использование локализации по умолчанию (фасет Беаяоп ю опгсртствует) // подраэпмевает ввод/вывод целых чисел: с!п» х; сои!«х«епь!1; 1оса!е!ос(!оса!е(), пего !/Б яеаяоп !о); // УБ яеаяоп ю определен ниже соиьлтЬие(1ос); //локализация сфасетол~ Беаяоп !о с!п.ипЬие(1ос); // локализация с фасетом Беаяоп !о ст»х; сои! «х к< епд1; Пусть имеется вход: яиогтег на выходе программы будет: яиттег Для получения этого результата мы должны определить 0Б яеаяоп ьо с целью задания строкового представления времен года и замещения (очеггЫе) функций Беаяоп со, преобразующих между строковыми представлениями и перечислениями: 965 Г 3.
Фасеты локализаций с!азз//Б зеазоп /о риЫ/сБеазоп со( я1иас сопи/ запив иеавопи(), риЫ!с: сопз1 я/г!пай 1о з/г(Беаиоп) сопвг Ьоо!/гот в/г(сопи/ в/г/пай, Беаяопй) сопя/; //обратите внимание, что (/Б "еозоп /о:Ядотсрпгстврет сопя/ я1ппвг !1$ веаяоп юззеазопзЦ = ( "зрппяг, яиттег.", '/а!!", 'лтп1ег" ), сопя/ в1ппдй (/$ зеазоп ьоз1о я/г($еаяоп х) сопи! /)( з<ирппЯ ги/п1ег<я) ( з1а1/с сопз1 и! ппя зв = "нет такого врез/сна года"; ге/игп ия; ) ге1игп зеавопи(х); ) Ьоо!!/Б иеазоп !о.агат ип(сопя/и1ппайз, Беазопйх) сопв1 сопя/ и/ппв ьея = йяеаяопя(ирппя)/ сопз1и1г/пд' епс/ = йиеаяопз(ипп1ег) + 1, сопя1 з/г/па* р =//пй(Ьеа, епс/, я); Яр==епд) ге1игп/а!ие; х = Беаяоп(р — Ьея); ге1игп 1гие; //рказател» зо последнии элемент" //э В.й/, э /$5.2 Заметьте, что поскольку Г/$ яеаяап ю является просто реалллзацией интерфейса Беаяоп ю, я не определял Ы для !/Б яеазоп ю.
В действительности, если мы захотим использовать //Б яеаяоп ю в качестве Беаяоп го, мы не вправе задавать для Г/Б яеаяоп ю его собственный Ы. Операции с локализациями, такие как /лая /асе1 (9 Г.3.1), полагают, что фасеты, реализующие одни и те же понят/ля, идентифицллруются одним и тем же Ы (9 ГЗ).
Единственный интересный вопрос реюлизации: что делать, если требуется вывести некорректный Беавоп. Естественно, этого не должно произойти. Однако случаи появления неверных значений простых определяемых пользователем классов не являются необычными, поэтому целесообразно принять во внимание подобную возможность. Я мог бы сгенерировать исключение. Но когда имеешь дело с простым выводом, предназначенным для человеческих глаз, полезно подготовить представление «вне диапазона» для недопустимых значений.
Обратите внимание, что при вводе стратегия обработки ошибок отдана на откуп оператору», тогда как при выводе политика обработки ошибок реализуется функцией фасета 1о я1г(). Это сделано с целью иллюстрации возможных альтернатив проектирования. В «промьцпленном проекте» функции фасета либо реализуют обработку ошибок и для ввода, и для вывода, либо сообщают обошибках операторам» и «, которые и заниматься обработкой ошибок. Обсуждаемый проект Беаяоп го полагается на то, что специфические для конкретной локализации строки предоставляются производными классами. Лльтернативный подход предполагае~, что Беаяоп го сам извлекает строки из соответствующего храни- Приложение Г Локализация лища (см.
з ГА.7). Создание класса Веазоп ю, которому строки времен года передают- ся как аргументы конструктора, оставляем в качестве упражнения (З Г.б)2)). Г.З.З. Использование локализаций и фасетов Г.4. Стандартные фасеты Стандартная библиотека предоставляет в <1оса1е> следующие фасеты для локалиэа- цглгл с1аахгс(~: Стандартные фасеты (локализацнн с1ахх1с~)) Категория Назначение Фасеты з Г.4А со11аге э Г.4.2 питепс со11аге<СЬ> питрипс1<С(г> пит уег<СЬ> пит ри1<СЬ> топеурипс1<СЬ> топеурипс1< СЬ, 1гие> топеу уе1<СЬ> топеу ри1<СЬ> 11те де1<СЬ> 1гте ри1<СЬ> с1уре<СЬ> сог1есв1<СЬ, сЬаг, тбв1а1е 1 пгеээадеэ<СЬ> Сравнение строк Ввод/вывод чисел ~ ГА.З топе1агу Ввогл/'вывод денег ~ Г.4.4 11те 5 ГА.5 с1уре з ГА.7 теээауез Вводувывод времени Классификация символов Выборка сообщений Локализации в первую очередь используются в потоках ввода гвьлвода стандартной библиотеки.
Однако механизм локализации является общим и расширяемым средством представления информации, зависящей от культурных особенностей, Класс пгеззадеэ Я ГА.7) является примером фасета, не имеюплего никакого отношения к потокам ввода/ вывода. Преимуществами локализаций могут воспользоваться расплирення потоковой библиотеки ввода/вывода и даже средства ввода1вывода, не основанные на потоках. Кроме того, пользователь может применять локализации в качестве удобного способа организации произвольной информации, связанной с культурными разли шями. Благодаря обплностн механизмов локализаций и фасетов, возможности определяемых пользователем фасетов не ограничены.
Вероятными кандидатамн на представ.ление фасетами являются даты, часовые пояса, телефонные номера, номера социального страхования (персональные идентификационные номера), коды товаров, температуры, произвольные пары вида (единица измерения, значение), почтовые коды, размеры одежды и международные номера книг (ЯВлч. Как и другими мощными механизмами, фасетами нужно пользоваться с осторожностью.
Из того факта, что нечто может быть представлено в виде фасета, не следует, что такое представление будет наилучшим. При выборе представления культурных зависимостей ключевыми являются, как всегда, следующие вопросы: каким образом различные решения оказывают влияние на сложность написания кода; насколько легко читается код; просто ли поддерживать программу; и насколько эффективны операциями ввода/вывода в плане времени выполнения и используемой памяти.
967 Г4. Стандартные фасеты В этой таблице СЬ означает сбаг или шсбаг 1. Пользователь, которому требуется, чтобы стандартный ввод/вывод работал с другим символьным типом Х, должен предоставить подходящие варианты фасетов Х. Например, для управления преобразованиями между Хи сбаг может потребоваться сойесп1<Х, сбаг, тбэ1а1е 1> Я ГА.6). Тип тбз1а1е 1 используется для представления состояния индикатора смещения в многобайтном представлении символов Я ГА,6); тбз1а1е 1 определен в <сшсбаг> и <шсбагб>.
Эквивалентом тЬз1а1е 1для произвольного символьного типа Хявляется сбаг 1га11з<Х>эз1а1е 1уре. Кроме перечисленных выше, стандартная библиотека предоставляет в <1оса1е> следующие фасеты: Стандартные фасеты Категория Назначение Фас еты соНа1е Ьупате<СЬ> питрипс1 бупате<СЬ> птп уе1<С, 7п> пит ри1<С, Ои1> топеурипс1 булате<СЬ, Гп1егпа11опа1> топеу де1<С, Гп> топеу ри1<С, Ои1> 1/те ри1 Ьупате<СЬ, Оиг> с1уре Ьупате<СЬ> Сравнение строк Ввод/вывод чисел 5 Г.44 со11ате э ГА.2 питег1с 6 Г.4З топе1агу Ввод/вывод денег 9 Г.4Л 11те 9 ГА.5 с1уре Ввод/вывод времени Классификация символов Выборкасообщений 9 Г.4.7 теваадез теэзауеэ Ьупате <СЬ> При инстанцировании фасета из этой таблицы, СЬ может быть сбаг нлц шсбаг 1; С может быть любым символьным типом Я 20А), Параметр 1п1егпа11опа1 может иметь значение «истина» или «ложь»; «истина» означает, что используется «интернациональное> чстырехсймвольное представление денежного знака Я ГА.3.1).
Тип тЬз1а1е 1 применяется для представления состояния индикатора смещения в много- байтном представлении символов Я Г.4.6); тЬз1а1е 1 определен в <сшсбаг> и <шсбапб>. Параметры!и н Ои1 — итераторы ввода и вывода соответственно Я 19. 1, 9 19.2А ). Снабжение фасетов ри1 н уе1 этими шаблонными аргументами позволяет программистуу реализовывать фасеты, которые осуществляют доступ к нестандартным буферам Ц ГА.2.2).
Буфера, связанные с потоками ввода/вывода, являются буферами потока, поэтому их итераторы нмекзт тпп оз1геатбиу 11ега1ог Я 19.2.6.1, 9 1'А.2.2). Следовательно, для обработки ошибок доступна функш«яуа11ег1() Я 19.2.6.1). «Расет Г булате является производным от фасета Г. пасет Г Ьупате предоставляет интерфейс, идентичный интерфейсу Г, за исключением того, что добавлен конструктор со строковым аргументом, именующим локализацию (см. 9 1.4А), Г булате)пате) предоставляет подходящую семантику для Г, определенного в 1оса1е)пате). Идея состоит в извлечении версии стандартного фасета из именованной локализации Ц Г.2.1) среды исполнения программы.
Например: 968 Приложение Г. Локализация ооЫ/(иес1огкк1г!пд> Й и, сопя1 !оса!ей !ос( ( !оса!е д!(!ос, пеки со!!а1е Ьупате'сЬаг>("г/а ((, // сравнение датских строк !оса!е г!Ь(г!1, пев с1уре Ьупатексдаг>("с!а'() // классификация дагпских сииволов ког1(и.Ьеу!и() о.епс(((, дЬ(; Эта новая локализация с(Ь будет пользоваться датскими строками, но в ней оставлены без изменений соглашения по умолчанию, касающиеся чисел.
Заметим, что поскольку второй аргумент фасета по умолчанию равен О, временем жизни фасета, созданного при помощи оператора пев, управляет локалкгзацияЯ Г.З). Подобно конструкторам локализации со строковыми аргументами, конструкторы Ьупате осуществлясот доступ к среде исполнения программы. Соответственно, они значительно медленнее, чем конструкторы, которым не нужно обращаться к среде окружения. Почти всегда быстрее сначала создать локализацию, а затем осуществлять доступ к ее фасетам, чем пользоваться фасетами Ьупате во многих местах программы. Таким образом, как правило хорошей идеей является однократное чтение фасета из среды окружения с последующим многократным использованием его копии в главной памяти (программы). Например: !оса1е сй('г1а (; //однократное чтение датскойлокилизаяии (всех еефасепгов) // затея используеи дЬ и ее фасегпы //помере необходияости ооЫ/(оес1ог к1ппд Й о, сопИ !оса!ей !ос( ( сопя1 со!!а1е<сдаг>й со! = ике /псе!<со!!а!в<сдпг»(с!Ь(.