Was sind die Kompromisse zwischen boost :: locale und std :: locale?

8

Ich bin dabei, eine große Legacy-Codebase in C ++ zu internationalisieren, und ich stehe vor einer schwierigen Entscheidung: Soll ich boost :: locale's oder std c ++ locales verwenden?

Ich bin verpflichtet, utf-8 zu verwenden. Wir müssen eine ziemlich breite Palette von Textverarbeitungen durchführen, obwohl es nicht der Kern dessen ist, was unser Code tut, ist es wichtig. Wir können erwarten, dass wir das meiste tun, was wir tun müssen: Formatierung von Zeit, Datum, Zahlen und Geld, Kollation, Regexp, Isolation von Teilstrings, Interaktion mit boost :: Dateisystem, DB-Zugriff, etc.

Die Einführung in boost :: locale bekomme ich das

  1. Das Festlegen der globalen Ländereinstellung hat Nebenwirkungen (z. B. csv). Es betrifft printf und boolst lexical_cast. Einige Bibliotheken von Drittanbietern können brechen.
  2. Die Formatierung von Zahlen ist in einigen Ländereinstellungen nicht möglich.
  3. Gebietsschema-Namen sind nicht standardisiert.
  4. Viele Anbieter bieten nur C und POSIX an, daher unterstützt GCC die Lokalisierung nur unter Linux.

Ich habe Schwierigkeiten, die Wirkung von Punkt 1 zu bewerten. Ich denke, Punkt 2 ist ziemlich streng, wenn es uns betrifft, werden die Anzeigen 3 und 4 für uns keine große Sache sein.

Gibt es in der Community einen Konsens, dass Boost :: locale die bessere Alternative ist? Gibt es eine Bewegung in der Standardgemeinde, um die Probleme mit std :: locale zu lösen? Kann mir jemand helfen, eine fundiertere Entscheidung zu treffen?

Vielleicht am wichtigsten, ist es einfach, von einem zum anderen zu migrieren? Wie gut spielen die beiden miteinander? Ist es legitim, das globale Gebietsschema mit einem Boost-Gebietsschema festzulegen und dann std facilities zu verwenden?

    
Spacemoose 06.08.2015, 15:44
quelle

2 Antworten

3

Am Ende ist die Boost-Dokumentation ein guter Job, um meine Frage zu beantworten, aber Sie müssen etwas lesen, und es hilft dabei, std::locale besser zu verstehen als zum Zeitpunkt der Veröffentlichung.

Spielt gut mit der Std

A std::locale ist eine Sammlung von facet s. Der Standard definiert eine Reihe von Facetten, die jedes Gebietsschema bereitstellen muss, aber abgesehen davon scheint es, dass die meisten der Implementierung überlassen werden. Dazu gehören das Gebietsschema und die Namen der Ländereinstellungen.

Was boost :: locale tut, ist eine Reihe von Facets, die in Locales gesammelt werden und sich unabhängig von der Plattform gleich verhalten (zumindest wenn Sie das Standard-ICU-Backend verwenden).

So bietet boost::locale eine standardisierte Menge von std :: locale's, die sich über alle Plattformen hinweg konsistent verhalten können, vollständige Unicode-Unterstützung für eine Vielzahl von kulturellen Normen bieten und konsistente Benennung. Der Wechsel zwischen der Verwendung einer Nicht-Boost-Komponente std::locale (d. H. Einer implementierten lokalen Umgebung) und einer boost::locale ist trivial, da sie die gleichen Typen sind - beide sind Sammlungen von std::facets , obwohl Implementierungen unterschiedlich sind. Wahrscheinlichkeiten sind die boost::locale s machen eine bessere Arbeit, was Sie wollen.

Komplette Unicode-Unterstützung für alle Kodierungen auf allen Plattformen
Ferner bietet boost::locale eine Möglichkeit, über die Intensivstation auf die vollständige Unicode-Unterstützung zuzugreifen, wodurch Sie ohne die Vorteile der Intensivstation profitieren können die schlechte (nicht C ++ ish) Schnittstelle von ICU.

Dies ist vorteilhaft, da jede Standardunterstützung von Unicode sehr wahrscheinlich über das locale frameork erfolgt und jedes Unicode-fähige Programm wahrscheinlich auch für das Gebietsschema sensibilisiert werden muss (z. B. für die Sortierung).

Besseres Verhalten in Bezug auf Zahlen Schließlich adressiert boost::locale , was in den üblichen Implementierungen von std :: locales berechtigterweise als signifikanter Fehler bezeichnet werden könnte - jede Stream-formatierte Zahl wird von der Ländereinstellung beeinflusst, unabhängig davon, ob dies wünschenswert ist - siehe Boost-Dokumentation für eine detaillierte Diskussion.

Wenn Sie also einen ofstream verwenden, um eine Datei zu lesen oder zu schreiben, und Sie haben die globale locale auf das deutsche Gebietsschema Ihrer Plattform gesetzt, dann haben Sie Kommas, die den Dezimalteil Ihrer Gleitkommazahlen trennen. Wenn Sie eine CSV-Datei lesen / schreiben, könnte das ein Problem darstellen. Wenn Sie ein boost::locale als globales Gebietsschema verwendet haben, geschieht dies nur, wenn Sie explizit angeben, dass Gebietsschema-Konventionen für Ihre numerische Eingabe / Ausgabe verwendet werden sollen. Beachten Sie, dass viele Bibliotheken Locale-Informationen im Hintergrund verwenden, einschließlich boost :: lexical_cast. Das gilt auch für std :: to_string. Betrachten Sie das folgende Beispiel:

%Vor%

Gibt die folgende Ausgabe aus:

%Vor%

In Code, der sowohl die menschliche Kommunikation (Ausgabe an GUI oder Terminal) als auch die Kommunikation zwischen Maschinen (CSV-Dateien, XML usw.) implementiert, ist dies wahrscheinlich unerwünschtes Verhalten. Wenn Sie ein Boost-Gebietsschema verwenden, geben Sie explizit an, wann die Gebietsschema-Formatierung verwendet werden soll, ala:

%Vor%

Fazit

Es scheint, dass boost :: locale den systemeigenen Locales vorgezogen werden sollte.

    
Spacemoose 10.09.2015, 13:26
quelle
1

Boost.Locale basiert auf dem std :: locale-Framework, bietet aber viel mehr sprachlich korrekte Optionen.

Auch wenn Sie utf-8 für Windows / MSVC verwenden möchten, ist std :: locale nicht verfügbar.

    
Artyom 24.08.2015 06:19
quelle