允许为std :: string分配“const char *”,但是不能编译分配给std :: wstring。为什么?

时间:2009-12-06 15:45:11

标签: c++ gcc stl g++

我假设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时,编译器会窒息。

编辑:通过删除文字“hello”的使用来改进示例。

#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)

7 个答案:

答案 0 :(得分:11)

你应该这样做:

#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 s的数组。

字符串文字前面的'L'表示您正在使用宽字符串常量。

答案 1 :(得分:6)

字符串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所说,如果这就是你的意思,那么最好首先使用宽字符串文字。

答案 2 :(得分:1)

小建议......不要在Linux(a.k.a。宽字符串)下使用“Unicode”字符串。 std::string非常好并且非常好地保存Unicode(UTF-8)。

大多数Linux API使用char *个字符串,最流行的编码是UTF-8。

所以......只是不要使用wstring打扰自己。

答案 3 :(得分:1)

要从多字节编码转换为宽字符编码,请查看标题<locale>和类型std::codecvt。 Dinkumware库有一个类Dinkum::wstring_convert,可以更轻松地执行这种多字节到宽的转换。

函数std::codecvt_byname允许人们为特定的命名编码找到codecvt实例。不幸的是,在系统上发现编码(或语言环境)的名称是特定于实现的。

答案 4 :(得分:0)

除了其他答案之外,您可以使用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!");

(注意:我的宏观功能很弱,这是未经测试的,但你明白了。)

答案 5 :(得分:0)

看起来你可以这样做:

    #include <sstream>
    // ...
    std::wstringstream tmp;
    tmp << "hello world";
    std::wstring our_string = 

虽然对于更复杂的情况,您可能想要分解并使用mbstowcs

答案 6 :(得分:-1)

你应该使用

#include <tchar.h>

tstring而不是wstring / string TCHAR *代替char * 和_T(“你好”)而不是“你好”或L“你好”

当定义_UNICODE时,这将使用相应形式的string + char。