Visual Studio C ++ 2015 std :: codecvt with char16_t或char32_t

时间:2015-08-17 16:29:30

标签: c++ stl visual-studio-2015 char16-t char32-t

此代码在VS2013下编译正常:

/{conversation-id}/messages

现在有了VS2015,我得到了:

std::string Unicode::utf16_to_utf8(std::u16string utf16_string)
{
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
    return convert.to_bytes(utf16_string);
}

4 个答案:

答案 0 :(得分:27)

旧问题,但供将来参考:这是Visual Studio 2015中的一个已知错误,正如MSDN Social this thread中最新帖子(2016年1月7日)所述。

您的示例的解决方法如下所示(为简单起见,我将您的方法实现为免费功能):

#include <codecvt>
#include <locale>
#include <string>
#include <iostream>

#if _MSC_VER >= 1900

std::string utf16_to_utf8(std::u16string utf16_string)
{
    std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert;
    auto p = reinterpret_cast<const int16_t *>(utf16_string.data());
    return convert.to_bytes(p, p + utf16_string.size());
}

#else

std::string utf16_to_utf8(std::u16string utf16_string)
{
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
    return convert.to_bytes(utf16_string);
}

#endif

int main()
{
    std::cout << utf16_to_utf8(u"Élémentaire, mon cher Watson!") << std::endl;

    return 0;
}

希望在将来的版本中解决问题,否则#if条件需要精炼。 更新:nope,未在VS 2017中修复。因此,我已将预处理器条件更新为>= 1900(最初为== 1900)。

答案 1 :(得分:7)

在cpp文件中定义缺少的符号。

// Apparently Microsoft forgot to define a symbol for codecvt.
// Works with /MT only
#include <locale>

#if (!_DLL) && (_MSC_VER >= 1900 /* VS 2015*/) && (_MSC_VER <= 1911 /* VS 2017 */)
std::locale::id std::codecvt<char16_t, char, _Mbstatet>::id;
#endif

答案 2 :(得分:3)

另一种可能的解决方法是为wstring_convert使用默认的第二个模板参数(wchar_t)。它适用于&#34; MS Visual Studio 2015更新3&#34;。请注意,不是与平台无关的解决方案。仅限Windows。

std::string utf16_to_utf8(std::u16string u16_string)
{
    std::wstring wide_string(u16_string.begin(), u16_string.end());
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
    return convert.to_bytes(wide_string);
}

答案 3 :(得分:3)

这在VS2017中对我有用:

std::wstring utf8_to_utf16(std::string utf8_string)
{
   return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>{}.from_bytes(utf8_string);
}

std::string utf16_to_utf8(std::wstring utf16_string)
{
    return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>{}.to_bytes(utf16_string);
}