2015-08-06 15 views
8

Sono in procinto di internazionalizzare un grande codebase legacy in C++ e mi trovo di fronte a una decisione difficile: dovrei usare boost :: locale o std C++ locales?Quali sono i compromessi tra boost :: locale e std :: locale?

Sono impegnato a utilizzare utf-8. Dobbiamo fare una gamma abbastanza ampia di elaborazione del testo, anche se non è il nucleo di ciò che fa il nostro codice, è importante. Possiamo aspettarci di fare la maggior parte di ciò che potrebbe essere necessario: tempo, data, numero, formattazione, confronto, regexp, isolamento della sottostringa, interazione con boost :: filesystem, accesso DB, ecc.

introduction to boost::locale I get that

  1. L'impostazione delle impostazioni internazionali globali ha effetti collaterali (esempio csv). Colpisce printf e boolst lexical_cast. Alcune librerie di terze parti possono rompere.
  2. La formattazione del numero è interrotta su alcune impostazioni locali.
  3. I nomi delle impostazioni internazionali non sono standardizzati.
  4. Molti fornitori forniscono solo C e POSIX, pertanto GCC supporta la localizzazione solo sotto Linux.

Ho difficoltà a valutare l'impatto del punto 1. Immagino che il punto 2 sia piuttosto grave se ci riguarda, l'annuncio 3 e 4 non sarà un grosso problema per noi.

C'è un consenso nella comunità che Boost :: locale è l'alternativa migliore? C'è qualche movimento nella comunità standard per risolvere i problemi con std :: locale? Qualcuno può aiutarmi a prendere una decisione più informata?

Forse, cosa più importante, è semplice migrare da uno all'altro? Quanto bene i due giocano l'uno con l'altro? È legittimo impostare le impostazioni internazionali globali con una locale boost e quindi utilizzare le funzionalità standard?

+0

Per lo meno, è necessario impostare personalmente std :: locale se si utilizza boost: http://www.boost.org/doc/libs/1_58_0/libs/locale/doc/ html/faq.html # faq_number – Buddy

risposta

3

Alla fine, la documentazione di boost fa un buon lavoro di risposta alla mia domanda, ma è necessario fare un po 'di lettura, e aiuta a capire std::locale meglio di quanto ho fatto al momento della pubblicazione.

Gioca bene con lo std

Un std::locale è una raccolta di facet s. Lo standard definisce un insieme di faccette che ogni locale deve fornire, ma a parte ciò sembra che la maggior parte sia lasciata all'implementazione. Ciò include il comportamento locale e i nomi delle impostazioni locali.

Cosa boost :: locale fornisce una serie di aspetti, raccolti in locale, che si comportano allo stesso modo indipendentemente dalla piattaforma (almeno se si utilizza il backend ICU predefinito).

Quindi boost::locale fornisce un set standardizzato di std :: locale che può comportarsi in modo coerente tra piattaforme, fornisce un supporto Unicode completo per un'ampia gamma di norme culturali e con denominazione coerente. Il passaggio tra l'uso di un boost std::locale (ad esempio un'implementazione fornita locale) e uno boost::locale è banale in quanto sono gli stessi tipi: entrambi sono raccolte di std::facets, sebbene le implementazioni siano diverse.Le probabilità sono le boost::locale s fare un lavoro migliore di fare quello che vuoi.

supporto Unicode completo, per tutte le codifiche, su tutte le piattaforme
Inoltre, boost::locale fornisce un modo di accedere supporto Unicode completo attraverso ICU, che consente di ottenere i benefici della terapia intensiva, senza il povero (non C + + ish) interfaccia di ICU.

Questo è vantaggioso, poiché è probabile che qualsiasi supporto standard di Unicode provenga dal frameork locale e probabilmente anche il programma di riconoscimento Unicode avrà bisogno di impostazioni locali (ad esempio per le regole di confronto).

comportamento Saner per quanto riguarda i numeri Infine, boost::locale indirizzi che cosa potrebbe legittimamente essere chiamato un difetto significativo nelle consuete implementazioni delle std :: locali - un numero qualsiasi flusso formattato sarà influenzato da locale, indipendentemente dal fatto che si tratta di desiderabile: vedere lo boost documentation per una discussione dettagliata.

Quindi, se si utilizza un ofstream per leggere o scrivere un file e si è impostato il globale locale nelle impostazioni locali tedesche della piattaforma, verranno visualizzate virgole che separano la parte decimale dei float. Se stai leggendo/scrivendo un file CSV, potrebbe essere un problema. Se hai usato uno boost::locale come locale globale, questo avverrà solo se dici esplicitamente di usare le convenzioni delle impostazioni locali per l'input/output numerico. Nota che molte librerie utilizzano le informazioni locali in background, tra cui boost :: lexical_cast. Così fa std :: to_string, del resto. Così si consideri il seguente esempio:

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"); 

ha pronunciato la seguente uscita:

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 

Nel codice che implementa sia la comunicazione umana (uscita a GUI o terminale) e la comunicazione inter-macchina (file CSV, XML, ecc) questo è probabilmente un comportamento indesiderabile. Quando si utilizza un locale spinta, si specifica in modo esplicito quando si vuole impostazioni internazionali di formattazione, ala:

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

Conclusione

Sembrerebbe che boost :: locale di dovrebbe essere preferito nel corso dei locali sistema previsto.

1

Boost.Locale è basato sul framework std :: locale ma offre molte più opzioni in un modo linguisticamente corretto.

Inoltre, se si desidera utilizzare utf-8 su windows/MSVC, std :: locale è vietato.

Problemi correlati