簡體   English   中英

允許為std :: string分配“const char *”,但是不能編譯分配給std :: wstring。 為什么?

[英]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::stringstd::basic_string<char>的typedef,而std::wstringstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM