【问题标题】:GCC 4.8 and char16_t streams - bug?GCC 4.8 和 char16_t 流 - 错误?
【发布时间】:2015-02-03 08:10:44
【问题描述】:

这是一个 libstdc++ 错误吗?

#include <string>
#include <sstream>

using namespace std;

int main() {
        basic_string<char16_t> str(u"0.0");
        basic_stringstream<char16_t> sstr(str);
        double x = 9;
        sstr >> x;
}

输出,在 GCC 4.8 Linux x86_64 下:

$ ./main
terminate called after throwing an instance of 'std::bad_cast'
  what():  std::bad_cast
Aborted (core dumped)

编辑有人可以建议一种方法来使这个函数在 GCC 4.9 下工作而不改变其签名:

template<typename T>
T fromString(std::basic_stringstream<char16_t>& stream)
{
    T v;
    stream >> v;
    return v;
}

典型用途是:

std::basic_string<char16_t> string(...);
std::basic_stringstream<char16_t> sstream(string);
double v = fromString<double>(sstream);

【问题讨论】:

  • 流不需要支持char16_tchar32_t,只有charwchar_t
  • 太棒了。那么,有没有办法使上述工作?
  • 解决方法提示:使用 utf-8 流,然后使用 utfcpp 等工具将字符串转换为 utf-16:utfcpp.sourceforge.net
  • 事实上它已经完全坏掉了,不是吗? std::basic_string&lt;char16_t&gt; s; stream &gt;&gt; s; 产生同样的异常。

标签: c++ gcc unicode iostream libstdc++


【解决方案1】:

该标准不要求实现支持除charwchar_t 之外的任何类型的流。

[iostreams.limits.pos]

在第 27 条的类中,名称为 charT 的模板参数表示包含 charwchar_t 和任何其他实现定义的满足字符要求的字符类型的类型集的成员可以在其上实例化任何 iostream 组件。

此外,它也不需要用于从流中提取整数和浮点数的构面来处理char16_t

[category.numeric]

22.4.2 子条款中num_putnum_get 的所有成员函数规范仅适用于表81 和82 (22.3.1.1.1) 中要求的特化,即num_get&lt;char&gt;num_get&lt;wchar_t&gt;num_get&lt;C, InputIterator&gt;num_put&lt;char&gt;num_put&lt;wchar_t&gt;num_put&lt;C,OutputIterator&gt;

C:

名为C 的模板参数表示包含的类型集 charwchar_t 以及任何其他实现定义的字符类型,它们满足可以实例化任何 iostream 组件的字符的要求。

标准只要求char_traits(以及basic_string)和codecvtchar16_tchar32_t 正常工作。

因此,要使您的函数正常工作,您基本上需要定义库未提供的所有缺失部分的特化。

【讨论】:

    猜你喜欢
    • 2013-05-28
    • 2018-01-07
    • 1970-01-01
    • 2016-04-07
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多