C++擁有的一件事是多個字符串或者說字符類型:char
,wchar_t
,char16_t
,char32_t
。因此,我們有不同的字符串類型定義:std::string
,std::wstring
,std::u16string
和std::u32string
,它們是不同的字符串類型。如果我們正在談論Windows和COM,那麼也有平臺類型,如BSTR
s。但是它並不止於此,如果我們正在談論Windows和COM,還有平臺類型,如BSTR
s。我們甚至還沒有開始談論 字符編碼。在新的C++庫中處理多個字符串類型
如果您正在構建一個新庫,並且其中一個需求是支持所有這些字符串類型或字符類型,那麼您將如何執行此操作?現在讓我們忘記字符編碼。
我在想這件事,我拿出幾個選項,但沒有一個是理想的。讓我們假設你有一個registry_key
類,它具有 支持所有這些字符類型,其OM的一部分或多或少(只說明它的一部分在這裏):
class registry_key
{
public:
registry_key(unspecified_string_type keyname);
unspecified_string_type name() const;
unspecified_string_type path() const;
}
你就可以使用它像:
registry_key key("HKLM\\Software\\Adobe");
std::string name = key.name();
但是,它必須支持其他字符串類型。此外,沒有要求整個registry_key
必須一致,只要字符類型去,或操作一個單一的字符類型。您可以調用構造函數並傳遞const char*
,但將密鑰的名稱作爲u16string
。這是下面的平臺的反映,它允許您在同一api集內調用wide(XxxW
)和narrow(XxxA
)apis。這種行爲是理想的。
對於構造函數(或帶參數的東西),這很簡單,因爲可以推導出類型。但是,對於返回字符串的函數而言,不會將任何內容作爲輸入,它不能。
至於選擇去,我有:
1)模板在STL與字符類型整個註冊表鍵,以同樣的方式basic_string
,和其他類型一樣。所以,你會
wregistry_key key(L"HKLM\\Software\\Adobe");
std::wstring name = key.name();
u8registry_key key(u8"HKLM\\Software\\Adobe");
std::u16string name = key.name();
的問題是,這並沒有真正規模這是相當可怕的,如果它被應用到了很多的類型,任何事情處理字符串。從某種意義上來說,這是一個糟糕的設計選擇,因爲有些類甚至沒有太多關於字符串的內容,所以爲什麼首先將它作爲模板參數傳遞。
2)採用和使用單個字符串類型,如u16string
或u32string
。但如上所述,這是違背目標的。
3)前綴字符類型的函數名:
registry_key key("HKLM\\Software\\Adobe");
std::string name = key.name();
std::wstring name = key.wname();
std::u16string name = key.u8name();
std::u32string name = key.uname();
這一點,但仍然redundand。
4)創建一個新的字符串類型,它根本不是字符串類型。它有一種方式可以存儲不同類型的字符串,並使用用戶定義的轉換運算符查詢並轉換爲其他類型的字符串。所以這將是自動的。
platform_string str = L"foo";
std::string sstr = str;
std::wstring swstr = str;
std::u16string su16str = str;
str = u"foo";
這將使寫註冊表類可能是這樣的:
class registry_key
{
public:
registry_key(unspecified_string_type keyname);
platform_string name() const;
platform_string path() const;
}
而且你可以使用它作爲:
registry_key key("HKLM\\Software\\Adobe");
std::string name = key.name();
std::wstring name = key.name();
std::u16string name = key.name();
的問題,這是引進的想法看起來像一個新的字符串類型,即使它不是真的。它感覺破碎了。
是否有比更好的解決方案3)和4)?或者更好的方法來解決這個問題?
依賴於平臺的'wchar_t'問題可以在C++ 11中繞過,它增加了'char16_t'類型 – Joe
@joe,但是這就是爲什麼我提到'wchar_t'與UTF-16分開的原因;) – Rook
我明白了,但是你可以提到這個替代方案已經存在了(並且是專門針對UTF-16的!) – Joe