2015-08-06 17 views
8

Tôi đang trong quá trình quốc tế hoá một bộ mã lớn kế thừa trong C++, và tôi đang phải đối mặt với một quyết định khó khăn: tôi có nên sử dụng boost :: locale's hoặc std C++ locales?Sự cân bằng giữa boost :: locale và std :: locale là gì?

Tôi cam kết sử dụng utf-8. Chúng ta phải thực hiện một phạm vi xử lý văn bản khá hợp lý, mặc dù nó không phải là cốt lõi của những gì mã của chúng ta làm, điều quan trọng. Chúng ta có thể mong đợi làm hầu hết những gì có thể cần làm: thời gian, ngày tháng, số và định dạng tiền, collation, regexp, cô lập chuỗi con, tương tác với boost :: filesystem, truy cập DB, v.v.

introduction to boost::locale I nhận được rằng

  1. Đặt ngôn ngữ chung có tác dụng phụ (ví dụ csv). Nó ảnh hưởng đến printf và boolst lexical_cast. Một số thư viện của bên thứ ba có thể bị hỏng.
  2. Định dạng số bị hỏng trên một số ngôn ngữ.
  3. Tên miền địa phương không được tiêu chuẩn hóa.
  4. Nhiều nhà cung cấp chỉ cung cấp C và POSIX, vì vậy GCC chỉ hỗ trợ bản địa hóa dưới Linux.

Tôi gặp khó khăn khi đánh giá tác động của điểm 1 Tôi đoán điểm 2 là khá nghiêm trọng nếu ảnh hưởng đến chúng tôi, quảng cáo 3 và 4 sẽ không phải là vấn đề lớn đối với chúng tôi.

Có sự đồng thuận nào trong cộng đồng rằng Boost :: locale là giải pháp thay thế tốt hơn không? Có bất kỳ chuyển động nào trong cam kết chuẩn để giải quyết các vấn đề với std :: locale's không? Có ai giúp tôi đưa ra quyết định sáng suốt hơn không?

Có lẽ quan trọng nhất, việc di chuyển từ người này sang người khác có đơn giản không? Hai người chơi với nhau như thế nào? Có hợp pháp để thiết lập miền địa phương toàn cầu với một miền địa phương tăng cường, và sau đó sử dụng các cơ sở std?

+0

Ít nhất, có vẻ như bạn sẽ cần đặt std :: locale mình nếu bạn sử dụng tăng: http://www.boost.org/doc/libs/1_58_0/libs/locale/doc/ html/faq.html # faq_number – Buddy

Trả lời

3

Cuối cùng, tài liệu tăng cường thực hiện tốt công việc trả lời câu hỏi của tôi, nhưng bạn phải thực hiện một số việc đọc và giúp hiểu được std::locale tốt hơn so với thời điểm tôi đăng.

Plays độc đáo với std

Một std::locale là một tập hợp các facet s. Tiêu chuẩn định nghĩa một tập hợp các khía cạnh mà mỗi miền địa phương phải cung cấp, nhưng khác hơn là có vẻ như phần lớn là còn lại để thực hiện. Điều này bao gồm hành vi địa phương và tên của các ngôn ngữ.

Tăng cường gì :: miền địa phương cung cấp một loạt các khía cạnh, được thu thập thành ngôn ngữ, hoạt động theo cùng một cách bất kể nền tảng (ít nhất là nếu bạn đang sử dụng phụ trợ mặc định của ICU).

Vì vậy, boost::locale cung cấp bộ tiêu chuẩn std :: locale có thể hoạt động nhất quán trên nhiều nền tảng, cung cấp hỗ trợ Unicode đầy đủ cho nhiều định dạng văn hóa và đặt tên nhất quán. Chuyển đổi giữa việc sử dụng số không tăng std::locale (tức là miền địa phương được cung cấp thực hiện) và boost::locale là tầm thường vì chúng là cùng loại - cả hai đều là các bộ sưu tập của std::facets, mặc dù việc triển khai khác nhau.Rất có thể là boost::locale s làm một công việc tốt hơn để làm những gì bạn muốn.

hỗ trợ Unicode đầy đủ, cho tất cả các mã hóa, trên tất cả các nền tảng
Hơn nữa, boost::locale cung cấp một cách tiếp cận hỗ trợ unicode hoàn chỉnh thông qua ICU, cho phép bạn để đạt được những lợi ích của ICU, mà không có sự nghèo (không phải C + + ish) giao diện của ICU. Đây là thuận lợi, vì mọi hỗ trợ chuẩn của Unicode rất có khả năng đi qua frameale locale, và bất kỳ chương trình nhận biết unicode nào cũng có khả năng cần phải nhận biết locale (ví dụ collation chẳng hạn).

hành vi saner về số Cuối cùng, boost::locale địa chỉ những gì hợp pháp có thể được gọi là một lỗ hổng quan trọng trong việc triển khai thông thường của std :: miền địa phương - bất kỳ số định dạng stream sẽ bị ảnh hưởng bởi địa phương, cho dù đây là mong muốn - xem boost documentation để có cuộc thảo luận chi tiết. Vì vậy, nếu bạn đang sử dụng một dòng để đọc hoặc viết một tập tin, và bạn đã thiết lập hình cầu là locale sang ngôn ngữ Đức của nền tảng của bạn, bạn sẽ có dấu phẩy tách phần thập phân của phao của bạn. Nếu bạn đang đọc/ghi một tệp csv, đó có thể là một vấn đề. Nếu bạn đã sử dụng boost::locale làm ngôn ngữ toàn cầu của mình, điều này sẽ chỉ xảy ra nếu bạn nói rõ ràng để sử dụng quy ước miền địa phương cho đầu vào/đầu ra số của bạn. Lưu ý rằng nhiều thư viện sử dụng thông tin địa phương trong nền, bao gồm tăng :: lexical_cast. Vì vậy, không std :: to_string, cho rằng vấn đề. Vì vậy, xem xét ví dụ sau:

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

Cung cấp đầu ra sau đây:

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 

Trong mã mà thực hiện cả giao tiếp con người (đầu ra để GUI hoặc thiết bị đầu cuối) và thông tin liên lạc giữa các máy (file csv, xml, vv) đây có thể là hành vi không thể xóa. Khi sử dụng một sự thúc đẩy địa phương, bạn chỉ định rõ ràng khi bạn muốn Locale định dạng, ala:

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

Kết luận

Dường như boost :: locale của nên được ưa thích hơn các miền địa phương hệ thống cung cấp.

1

Boost.Locale dựa trên std :: khuôn khổ miền địa phương nhưng cung cấp nhiều tùy chọn hơn theo cách đúng ngữ pháp hơn.

Ngoài ra nếu bạn muốn sử dụng utf-8 trên windows/MSVC, std :: locale is no-go.

Các vấn đề liên quan