繁体   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