c++ - 将 wstring 转换为 string 的古代代码中的可怕警告

标签 c++ visual-studio c++17

旧方法包含如下代码(匿名):

        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/

相关文章:

c++ - 如何让 __declspec(thread) 在 Windows CE 上工作

c++ - 管理模板派生类型的 vector 集合

c# - 自定义 XML 文档的验证模式

c++ - 为什么 sizeof(std::variant) 与具有相同成员的结构的大小相同?

c++ - C++17和C++11中的非类型模板参数有什么区别?

c++ - ofstream 不在 Windows 子系统中为 Linux 生成新行

c++ - 如何破坏 C++ 接受函数?

visual-studio - 不在资源 View 中时隐藏属性/工具箱 Pane ?

c# - 为什么不建议在同一个解决方案中混合使用 VB.Net 和 C#?

c++ - 调用基本构造函数时是否应该复制继承构造函数的参数?