【问题标题】:Preparing for char8_t in C++ 17在 C++ 17 中为 char8_t 做准备
【发布时间】:2019-11-07 19:30:40
【问题描述】:

我正在使用 Microsoft Visual C++ 16.1(2019 社区)并尝试编写在 C++ 2020 中“正确”的代码,预计该代码将具有 char8_t 类型,该类型将是无符号字符。我定义了一个这样的类型:

using char8_t = unsigned char;

代码如下:

std:string data;
const char8_t* ptr = data.c_str ();

无法编译,因为它不会在没有 reinterpret_cast 的情况下将有符号字符指针转换为无符号字符指针。我可以做些什么来为 2020 年做准备,而无需到处重新解释演员表吗?

【问题讨论】:

  • char8_t 出现时,std::u8stringstd::basic_string 也将专门用于char8_t。在处理 UTF-8 字符串时,不要将 std::stringstd::u8string 混合在一起。
  • "这将是一个无符号字符" char8_t 不是这样工作的。它是一种独特的类型,与 unsigned char 不同,尽管它可以显式且无损地转换为/从它们。
  • using char8_t = char;

标签: c++


【解决方案1】:

感谢 cmets。 cmets 和进一步的研究纠正了引发原始问题的一个主要误解。我现在明白了 2020 char8_t 不是 UTF-8 字符,而 2020 u8stringnot UTF-8 字符串。虽然它们可能用于“UTF-8 字符串”实现,但它们并非如此。

因此,使用reinterpret_cast 似乎是不可避免的,但可以隐藏/隔离到一组内联函数重载(或一组函数模板)。有必要将 utf8string 对象(可能作为模板)实现为不同的对象(如果在某些地方尚不可用)。

【讨论】:

    【解决方案2】:

    P1423 (char8_t backward compatibility remediation) 记录了许多方法,这些方法可用于补救由于通过P0482 (char8_t: A type for UTF-8 characters and strings) 采用char8_t 而造成的向后兼容性影响。

    因为char8_t 是一种非别名类型,所以使用reinterpret_cast 是未定义的行为,例如,将char8_t 指针分配给指向char 的指针,如reinterpret_cast<const char8_t*>(data.c_str())。但是,因为charunsigned char 可以为任何类型起别名,所以可以在另一个方向使用reinterpret_cast,例如reinterpret_cast<const char*>(u8"text")

    P1423 中记录的补救方法都不是灵丹妙药。您需要评估最适合您的用例的方法。您可能还会欣赏C++20 with u8, char8_t and std::string 中的答案。

    关于 char8_t 不是 UTF-8 字符和 u8string 不是 UTF-8 字符串,这是正确的,char8_t 是代码单元类型(不是代码点类型)并且u8string 不强制执行格式正确的 UTF-8 序列。但是,这些类型的意图是仅用于 UTF-8 数据。

    【讨论】:

      猜你喜欢
      • 2010-10-17
      • 1970-01-01
      • 2014-07-25
      • 2017-06-24
      • 2010-09-10
      • 1970-01-01
      • 1970-01-01
      • 2014-11-23
      • 1970-01-01
      相关资源
      最近更新 更多