[英]Why is a string literal copied when assigning to a const std::string?
[英]Assigning a “const char*” to std::string is allowed, but assigning to std::wstring doesn't compile. Why?
我假設std :: wstring和std :: string都提供了或多或少相同的接口。
所以我嘗試為我們的應用程序啟用unicode功能
# ifdef APP_USE_UNICODE
typedef std::wstring AppStringType;
# else
typedef std::string AppStringType;
# endif
但是,當使用-DAPP_USE_UNICODE時,這會給我帶來很多編譯錯誤。
事實證明,當const char[]
被分配給std::wstring
時,編譯器會扼殺。
編輯 :通過刪除文字“你好”的使用改進的例子。
#include <string>
void myfunc(const char h[]) {
string s = h; // compiles OK
wstring w = h; // compile Error
}
為什么會有這樣的差異?
允許將const char*
分配給std::string
,但是分配給std::wstring
會產生編譯錯誤。
std::wstring
不應該提供與std::string
相同的接口嗎? 至少對於這樣的基本操作如賦值?
(環境:Ubuntu Karmic 32bit上的gcc-4.4.1)
你應該做:
#include <string>
int main() {
const wchar_t h[] = L"hello";
std::wstring w = h;
return 0;
}
std::string
是std::basic_string<char>
的typedef,而std::wstring
是std::basic_string<wchar_t>
的typedef。 因此, wstring
的“等效”C字符串是wchar_t
的數組。
字符串文字前面的“L”表示您正在使用寬字符串常量。
字符串API的相關部分是這個構造函數:
basic_string(const charT*);
對於std :: string,charT是char。 對於std :: wstring,它是wchar_t。 所以它不編譯的原因是wstring沒有char *構造函數。 為什么wstring沒有char *構造函數?
沒有一種獨特的方法可以將char字符串轉換為wchar字符串。 char字符串使用的編碼是什么? 它只是7位ASCII嗎? 是UTF-8嗎? 是UTF-7嗎? 它是SHIFT-JIS嗎? 所以我不認為std :: wstring從char *自動轉換是完全有意義的,即使你可以覆蓋大多數情況。 您可以使用:
w = std::wstring(h, h + sizeof(h) - 1);
它會將每個char依次轉換為wchar(NUL終結符除外),在這個例子中,這可能就是你想要的。 正如int3所說,如果這就是你的意思,那么最好首先使用寬字符串文字。
要從多字節編碼轉換為寬字符編碼,請查看標頭<locale>
和類型std::codecvt
。 Dinkumware庫有一個Dinkum::wstring_convert
類,可以更輕松地執行這種多字節到寬的轉換。
函數std::codecvt_byname
允許查找特定命名編碼的codecvt
實例。 不幸的是,在系統上發現編碼(或語言環境)的名稱是特定於實現的。
小建議......不要在Linux(也就是寬字符串)下使用“Unicode”字符串。 std::string
非常好並且非常好地保存Unicode(UTF-8)。
大多數Linux API使用char *
字符串,最流行的編碼是UTF-8。
所以...只是不要使用wstring打擾自己。
除了其他答案之外,您可以使用Microsoft的書(特別是tchar.h
)中的技巧,並編寫如下內容:
# ifdef APP_USE_UNICODE
typedef std::wstring AppStringType;
#define _T(s) (L##s)
# else
typedef std::string AppStringType;
#define _T(s) (s)
# endif
AppStringType foo = _T("hello world!");
(注意:我的宏觀功能很弱,這是未經測試的,但你明白了。)
看起來你可以這樣做:
#include <sstream>
// ...
std::wstringstream tmp;
tmp << "hello world";
std::wstring our_string =
雖然對於更復雜的情況,您可能想要分解並使用mbstowcs
你應該使用
#include <tchar.h>
tstring而不是wstring / string TCHAR *而不是char *和_T(“hello”)而不是“hello”或L“hello”
當定義_UNICODE時,這將使用適當形式的string + char。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.