2015-08-06 27 views
8

Jestem w trakcie internacjonalizacji dużego kodu źródłowego w C++ i mam do czynienia z trudną decyzją: czy powinienem używać kryteriów boost :: locale lub std C++?Jakie są kompromisy między boost :: locale i std :: locale?

Jestem zobowiązany do używania utf-8. Musimy wykonać dość szeroki zakres przetwarzania tekstu, chociaż nie jest to rdzeń tego, co robi nasz kod, jest to ważne. Możemy spodziewać się większości czynności, które trzeba wykonać: czasu, daty, liczby i formatowania pieniędzy, sortowania, wyrażeń regularnych, izolacji podłańcuchowych, interakcji z systemem boost :: files, dostępem do bazy danych itp.

The introduction to boost::locale I get the

  1. Ustawienie globalnych ustawień narodowych ma efekty uboczne (przykład CSV). Wpływa na printf i boolst leksykalny_cast. Niektóre biblioteki stron trzecich mogą się zepsuć.
  2. Formatowanie liczb jest uszkodzone w niektórych ustawieniach narodowych.
  3. Nazwy ustawień regionalnych nie są ustandaryzowane.
  4. Wielu dostawców udostępnia tylko C i POSIX, więc GCC obsługuje lokalizację tylko pod Linuksem.

Mam problem z oceną wpływu punktu 1 Sądzę, że punkt 2 jest dość poważny, jeśli dotyczy nas, reklamy 3 i 4 nie będą dla nas dużą sprawą.

Czy w społeczności istnieje consensus, że Boost :: locale jest lepszą alternatywą? Czy jest jakiś ruch w standardowej commity, aby rozwiązać problemy z std :: locale? Czy ktoś może mi pomóc w podjęciu bardziej świadomej decyzji?

A może najważniejsze jest to, że migrację z jednego do drugiego? Jak dobrze grają ze sobą? Czy jest uzasadnione, aby ustawić globalne ustawienia regionalne z locale doładowania, a następnie użyć urządzeń STD?

+0

Wygląda na to, że będziesz musiał ustawić std :: locale, jeśli użyjesz boost: http://www.boost.org/doc/libs/1_58_0/libs/locale/doc/ html/faq.html # faq_number – Buddy

Odpowiedz

3

Ostatecznie, dokumentacja doładowania dobrze odpowiada na moje pytanie, ale musisz przeczytać trochę, a to pomaga lepiej zrozumieć std::locale niż ja w momencie publikacji.

Plays ładnie z std

std::locale jest zbiorem facet s. Standard definiuje zestaw aspektów, które muszą zapewnić poszczególne lokalizacje, ale poza tym wydaje się, że większość pozostaje do realizacji. Obejmuje to zachowanie ustawień narodowych i nazwy ustawień narodowych.

Co doładowania :: locale to zapewnia kilka aspektów zebranych w lokalizacjach, które zachowują się tak samo niezależnie od platformy (przynajmniej jeśli korzystasz z domyślnego zaplecza ICU).

Tak więc boost::locale zapewnia ustandaryzowany zestaw std :: locale, który może zachowywać się konsekwentnie na różnych platformach, zapewnia pełne wsparcie dla Unicode dla szerokiego zakresu norm kulturowych i spójne nazewnictwo. Przełączanie między używaniem nieobsługiwania std::locale (tj. Implementacja dostarczona locale) i boost::locale jest trywialne, ponieważ są one tego samego typu - oba są kolekcjami std::facets, chociaż implementacje są różne.Szanse są na to, że lepiej wykonują to, co chcesz.

Pełne wsparcie Unicode, dla wszystkich kodowań, na wszystkich platformach
dalej, boost::locale dostarcza sposób dostępu pełną obsługę Unicode poprzez ICU, która pozwala na uzyskanie korzyści z OIOM, bez ubogich (nie C + + ish) interfejs ICU.

Jest to korzystne, ponieważ wszelkie standardowe wsparcie dla Unicode jest bardzo prawdopodobne, że przejdzie przez ramę ustawień regionalnych, a każdy program obsługujący unikod będzie prawdopodobnie również potrzebować locale (na przykład do sortowania).

Saner zachowanie dotyczące numerów Wreszcie boost::locale adresy co mógł zasadnie nazwać znacząca wada w typowych implementacjach std :: lokalizacjach - dowolna liczba strumień sformatowana zostanie dotkniętych lokalizacji, niezależnie od tego, czy jest to pożądane - zobacz szczegółową dyskusję na stronie boost documentation.

Tak więc, jeśli używasz czytnika do odczytu lub zapisu pliku, a ustawiłeś globale locale na niemieckie ustawienia narodowe Twojej platformy, będziesz mieć przecinki oddzielające dziesiętną część twoich spławów. Jeśli czytasz/piszesz plik csv, może to być problem. Jeśli używałeś boost::locale jako globalnego ustawienia narodowego, stanie się to tylko wtedy, gdy wyraźnie powiesz mu, aby używał konwencji narodowych dla twojego numerycznego wejścia/wyjścia. Zwróć uwagę, że wiele bibliotek korzysta z informacji o lokalizacji w tle, w tym do funkcji boost :: lexical_cast. Tak samo jak std :: to_string. Więc rozważyć następujący przykład:

std::locale::global(std::locale("de_DE")); 

auto demo = [](const std::string& label) 
{ 
    std::cout.imbue(std::locale()); // imbue cout with the global locale. 
    float f = 1234.567890; 
    std::cout << label << "\n"; 
    std::cout << "\t streamed: " << f << "\n"; 
    std::cout << "\t to_string: " << std::to_string(f) << "\n"; 
}; 

std::locale::global(std::locale("C"));//default. 
demo("c locale"); 

std::locale::global(std::locale("de_DE"));//default. 
demo("std de locale"); 

boost::locale::generator gen; 
std::locale::global(gen("de_DE.UTF-8")); 
demo("boost de locale"); 

daje następujący wynik:

c locale 
    streamed: 1234.57 
    to_string: 1234.567871 
std de locale 
    streamed: 1.234,57 
    to_string: 1234,567871 
boost de locale 
    streamed: 1234.57 
    to_string: 1234,567871 

W kodzie, który implementuje zarówno komunikacji międzyludzkiej (wyjście do GUI lub terminal) oraz komunikację między-maszyna (CSV plików XML, itp.) jest to prawdopodobnie niepożądane zachowanie. Używając locale doładowania, należy wyraźnie określić, kiedy chcesz locale formatowanie, ala:

cout << boost::locale::as::currency << 123.45 << "\n"; 
cout << boost::locale::as::number << 12345.666 << "\n" 

Wnioski

Wydaje się, że boost :: lokalna powinna być bardziej korzystne niż system przewidziany w lokalizacjach.

1

Boost.Locale jest oparty na strukturze std :: locale, ale zapewnia znacznie więcej opcji w bardziej poprawny językowo sposób.

Również jeśli chcesz używać utf-8 na windows/MSVC, std :: locale nie działa.