如何让 wstring_convert::to_bytes 抛出 range_error 异常?

Cla*_*ton 5 c++ unicode unit-testing std visual-studio-2015

我正在使用std::wstring_convert将 wstring 转换为多字节字符串,如下所示:

    // convert from wide char to multibyte char
    try
    {
        return std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(wideMessage);
    }

    // thrown by std::wstring_convert.to_bytes() for bad conversions
    catch (std::range_error& exception)
    {
        // do something...
    }
Run Code Online (Sandbox Code Playgroud)

为了对块进行单元测试,我已经评论过,因为do something...我希望传递一个会引发std::range_error异常的 wstring 。

但是,我还没有能够制定出这样的 wstring 会导致这种转换失败。wstring 将使用 UTF16,我一直在阅读有关高和低代理的信息。例如,D800 后跟“b”的 UTF16 字符应该是无效的。 std::wstring(L"\xd800b");可能无法以相同的理由编译。如果我创建一个像下面这样的 wstring,它不会在转换时抛出异常:

std::wstring wideMessage(L" b");
wideMessage[0] = L'\xd800';

// doesn't throw
std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(wideMessage);
Run Code Online (Sandbox Code Playgroud)

在转换过程中是否有合适的 wstring 可以用来抛出异常?

我已经从这个链接尝试了 5.1、5.2 和 5.3 。我正在使用 Visual Studio 2015。

一二三*_*一二三 5

Microsoft 的实现std::codecvt_utf8似乎成功地将任何 UTF-16 代码单元转换为 UTF-8——包括代理对。这是一个错误,因为代理不可编码。libc++ (LLVM) 和 libstdc++ (GCC) 都会正确抛出 astd::range_error并且无法转换未配对的代理项。

查看他们的代码,似乎它抛出的唯一方法是字符大于Maxcode构面的模板参数。例如:

std::wstring_convert<std::codecvt_utf8<wchar_t, 0x1>>
Run Code Online (Sandbox Code Playgroud)