当我执行以下操作时,我的编译器警告我可能会丢失数据(但编译成功):
std::vector<wchar_t> v1;
v1.push_back(L'a');
std::vector<char> v2(v1.begin(), v1.end());
当我执行以下操作时,我没有得到这样的警告,据我所知,我在过去完成时没有丢失数据:
std::wstring w1;
w1 = L"a";
std::string s1(w1.begin(), w1.end());
实际上第二个片段中是否存在数据丢失的可能性?如果,不是为什么不呢? basic_string构造函数中是否有某些东西可以处理其他类型字符的迭代器的可能性?或者它是迭代器本身的特殊之处吗?
答案 0 :(得分:1)
是的,第二个代码段将以与第一个代码段相同的方式丢失数据(截断字符值)。您的库实现可能正在做一些抑制警告消息的事情。如果不查看特定库实现的来源,就不可能知道。
答案 1 :(得分:1)
举一个具体的例子,如果你写
std::wstring w1 = L"τ"; // That's a Unicode Greek Small Letter Tau (U+03C4)
std::string s1(w1.begin(), w1.end());
最有可能你最终得到一个包含字符0xC4的字符串,这是Windows ANSI和ISO Latin-1中的“Ä”。这可能不是你想要的,虽然它可以在大多数平台上正常工作如果你坚持使用ASCII ,即使这样也不能保证(例如,如果你的代码在IBM大型机上运行,你可能会发现窄字符串是EBCDIC,宽字符串可以是任意数量的异常编码。
如果要将宽字符串转换为窄字符串,则需要使用适当的函数来处理涉及字符编码的事实。 C ++并没有提供一个体面的方法来做到这一点;通常,您必须恢复为C的wctombs()
函数,或使用特定于平台的API。 (有人可能会指向narrow
ctype
方面,但这只是意味着任何无法用单个字节表示的字符都会被指定的字符替换;这并不是真正的转换。此外,C ++ 11支持使用wstring_convert
在Unicode字符串之间进行转换,但这只能处理Unicode,并不是每个人都使用它来处理窄字符和宽字符。)