【问题标题】:Why is std::u16cout missing?为什么 std::u16cout 不见了?
【发布时间】:2011-08-26 14:13:29
【问题描述】:

C++03 定义了两种字符类型:charwchar_t。 (让我们忽略 signed charunsigned char 的疯狂)。

然后将这两个字符应用于std::basic_stringstd::basic_ostream 等,如std::string/std::wstringstd::ostream/std::wostream

标准库还从流中定义了全局变量std::coutstd::wcout

新的 c++0x 标准定义了另外两种字符类型 char16_tchar32_t。但是,唯一的新 typedef 是 std::u16stringstd::u32string

为什么标准不提供std::u16ostream?或者std::u32cout 怎么样?

【问题讨论】:

  • 你认为它为什么需要它们?流只是一个字节序列。它是否降低了以不同格式写入和读取流的可能性?不,Once 可以使用 std::ostream 编写一个流并使用 std::u16stream 读取,并且这些流可以正常工作(因此没有额外的保护来防止做错事)。因此,将流读入正确类型的对象的责任仍然落在程序员身上,因为没有真正的方法来确定传入流的类型(它只是一个字节序列)。
  • 诚然,std::u32cout 不太可能被经常使用。我只能想象国际化应用程序的控制台输出。但是,std::u32ofstream 将立即有用。
  • @deft_code:我不明白这有什么用。您将需要更详细地解释为什么您认为这很有用。您正在将存储格式硬编码到流中,但您无法检测流是否实际上是使用该格式创建的。
  • @Martin:我不太了解你。有没有办法检测 ASCII/Latin-1/UTF-8 流的格式(在这个词的通用、非 C++ 意义上)?您总是需要提前(或通过使用商定的方法)知道您获得的流是使用哪种格式创建的。对于 UTF-x 流,您始终可以使用 BOM 来检测您正在处理的流类型。
  • @Martin:正如我之前所说,使用正确的 codecvt 方面,关心流大小的用途很少。它很可能是一个内部实现细节。但是有非常正当的理由希望 序列化格式 不是 UTF-8,如果您知道自己在做什么,就很容易检测到它。

标签: c++ unicode io c++11


【解决方案1】:

我不知道官方原因。

但我不认为需要一个。
通过拥有特定类型的流,您可以在那里使用硬编码。我更喜欢通用的流(处理字节),然后您可以自定义以输出为特定格式。就像他们目前的工作一样。

所以在内部我想使用 UTF16 字符串。但在输出时,我想将它们序列化为 UTF8 进行存储。为此,我将简单地创建一个普通流,为其注入一个知道如何从 UTF16 转换为 UTF8 的语言环境,然后所有流需要做的就是处理字节。

让流了解磁盘上的格式对您来说很少。拥有可以在不同格式之间转换的语言环境(在设备上转换为内部格式,反之亦然)非常方便。

【讨论】:

  • 有时您希望序列化为 UTF-16 或 UTF-32 - 主要是为了与其他软件兼容(例如,某些 Windows 文件格式使用 UTF-16)。但我想你仍然可以使用正确的 codecvt facet 将它们与普通字节流一起使用。
  • @Boaz Yaniv:我绝对希望能够以特定格式进行序列化。但我认为流不应该控制它。将一种表示转换为另一种表示是本地人的工作。当您将字符串序列化为文件时,您需要知道要序列化它的格式,并且在读回它时还需要知道此信息。这是通过为流注入适当的本地来完成转换的。
  • 讨厌吹毛求疵,但这是“语言环境”,而不是“本地”。
  • @Martin:这正是我所说的。使用 codecvt facet 为流注入可能足以使 u32/u16 流的大部分使用变得多余。
  • @Martin:所以对你来说,难题是为什么std::wostream 存在,而不是为什么std::u16ostream 不存在?
【解决方案2】:

我们认为实现 Unicode iostream 的工作量太大,不值得: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2238.html

来自论文:

省略这两种新类型的流特化的理由是非字符类型的流没有吸引广泛的使用,因此不清楚是否真的需要将这种非常复杂的机器的特化数量加倍。

据我了解,标准委员会意识到序列化为宽字符(2 或 4 字节格式)并不常见,在需要 UTF-16 或 UTF-32 的地方,您始终可以使用相同的基于 char 的旧字节流,但带有 codecvt 方面会将您的输入转换为 UTF-16/UTF-32,它可以将其视为另一种多字节格式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多