旧方法包含如下代码(匿名):
std::wstring wstr = ...;
std::string str(wstr.begin(), wstr.end());
以前,这一切都是在没有警告的情况下编译的,但随着我们更新到 C++17 和 VS2019 (v142) 以及整洁的项目设置,它现在会给出这些可怕的警告:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2468,23): warning C4244: 'argument': conversion from 'wchar_t' to 'const _Elem', possible loss of data
with
[
_Elem=char
]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2479): message : see reference to function template instantiation 'void std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Construct<wchar_t*>(_Iter,const _Iter,std::input_iterator_tag)' being compiled
with
[
_Iter=wchar_t *
]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2479): message : see reference to function template instantiation 'void std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Construct<wchar_t*>(_Iter,const _Iter,std::input_iterator_tag)' being compiled
with
[
_Iter=wchar_t *
]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2459): message : see reference to function template instantiation 'void std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Construct<wchar_t*>(const _Iter,const _Iter,std::forward_iterator_tag)' being compiled
with
[
_Iter=wchar_t *
]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\include\xstring(2459): message : see reference to function template instantiation 'void std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Construct<wchar_t*>(const _Iter,const _Iter,std::forward_iterator_tag)' being compiled
with
[
_Iter=wchar_t *
]
message : see reference to function template instantiation 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string<std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>,0>(_Iter,_Iter,const _Alloc &)' being compiled
with
[
_Elem=wchar_t,
_Iter=std::_String_iterator<std::_String_val<std::_Simple_types<wchar_t>>>,
_Alloc=std::allocator<char>
]
message : see reference to function template instantiation 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string<std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>,0>(_Iter,_Iter,const _Alloc &)' being compiled
with
[
_Elem=wchar_t,
_Iter=std::_String_iterator<std::_String_val<std::_Simple_types<wchar_t>>>,
_Alloc=std::allocator<char>
]
我非常确定这段代码早于我们代码库中 UNICODE 的使用 - 它似乎可以工作,但我不太明白这些警告或我应该采取什么措施。
我发现了这个问题:UTF8 to/from wide char conversion in STL但这个漂亮整洁的解决方案有评论说它在 C++17 中已被弃用!为什么这段代码首先混合 string 和 wstring 有点神秘,有一个简单的解决方案吗?或者这是一个“如果有效就留下它?!”的情况。
最佳答案
问题是您正在从 16 位字符串转换为 8 位字符串。由于 16 位比 8 位保存更多数据,因此数据将会丢失。如果您要在 UTF-16 和 UTF-8 之间进行转换,则需要使用转换库来正确完成此操作。
C++ 确实提供了以下形式的转换库:codecvt (在 C++17 中已弃用,但仍存在一段时间)。
如果您确定字符串仅包含 ASCII,则可以抑制警告。
参见https://en.cppreference.com/w/cpp/locale/codecvt_utf8_utf16了解详情
关于c++ - 将 wstring 转换为 string 的古代代码中的可怕警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68364773/