2017-03-11 4 views
0

C++ 빌더 10.1 (Clang 3.3)과 함께 새로운 C++ 11 Win32/64 프로젝트를 계획 중이고 핵심 기능에 관해서는 가장 휴대하기 쉬운 방식으로 구현할 생각입니다. std::string 인코딩을위한 UTF-8 (또한 SQLiteCpp의 기본 인코딩이기 때문에 사용하려는 SQLite C++ 래퍼). 는 I가 <codecvt>에서 .to_bytes().from_bytes() 기능을 사용하기로 결정 윈 - API 's 및 <locale>std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>>와의 상호 작용을위한std :: wstring_convert를 넣을 곳 <std :: codecvt_utf8 <wchar_t>>?

.

이제, 변환기 개체를 배치하는 가장 좋은 방법은 무엇인지 알고 싶습니다.

고유 한 단위 및 네임 스페이스를 지정해야합니다.

... 
#include <codecvt> 
#include <locale> 

namespace cnv 
{ 
    extern std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> wcu8; 
} 
... 

통화 당 :

.H

... 
namespace cnv 
{ 
    std::wstring_convert<std::codecvt_utf8<wchar_t>> wcu8; 
} 
... 

하고는 모든 곳에서 필요 cnv::wcu8.to_bytes(xyz)를 사용하여 포함되어 있습니까?

아니면 인코딩간에 변환해야하는 각 함수 구현 내에서 인스턴스를 만드는 것이 더 낫습니까?

+1

유일한 의도가 WIn32/64 인 경우 왜 휴대용이 필요합니까? 그렇다면 변환을 잊어 버리고 wstring 만 사용하면됩니다. – Brandon

+1

지금 Windows * 용 *이며 다른 시스템 용으로 나중에 컴파일 될 수 있습니다. – FlKo

+1

'std :: wstring_convert'에 대한 저의 경험은 GCC와 clang이 잘 지원하지 않는다는 것입니다. 특히 Travis CI의 기본 컴파일러는'codecvt' 헤더를 포함하여 질식합니다. 그냥 내 두 센트. – rwols

답변

1

전역 변수에 std::wstring_convert을 저장하지 않을 것입니다. 이는 스레드로부터 안전하지 않고 많은 것을 구입하지 않기 때문입니다. 필요할 때마다 std::wstring_convert의 인스턴스를 생성하면 성능이 저하 될 수 있지만 처음에는 문제가되지 않습니다 (조기 최적화).

그래서 난 그냥 함수로 그 일을 감싸는 것 :

std::wstring utf8_to_wstr(const std::string& utf8) { 
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> wcu8; 
    return wcu8.from_bytes(utf8); 
} 

std::string wstr_to_utf8(const std::wstring& utf16) { 
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> wcu8; 
    return wcu8.to_bytes(utf16); 
} 

당신은 어딘가에 std::range_error 예외를 잡을 수 있습니다. 어떤 이유로 든 변환이 실패하면 (잘못된 코드 포인트 등) std::wstring_convert에 의해 throw 될 수 있습니다.

나중에 문자열 변환과 관련하여 성능 병목 현상이 발생하더라도 코드의 중요한 부분에 직접 std::wstring_convert을 직접 인스턴스화 할 수 있습니다 (예 : std::wstring_convert). 지. 많은 문자열을 변환하는 장기 실행 루프 외부.