在 C++17 和 C++20 之间可移植地使用 UTF-8 字符串文字前缀

Hum*_*ler 5 c++ utf-8 string-literals c++17 c++20

我有一个用 C++17 编写的代码库,它大量使用 UTF-8,以及u8c++11 中引入的字符串文字来指示 UTF 编码。然而,c++20 将C++ 中u8文字的含义从生成 a charor更改const char*为 a char8_tor const char8_t*;后者不能隐式指针转换const char*.

我希望这个项目能够支持在 C++17 和 C++20 模式下运行而不会出现中断;可以采取什么措施来支持这一点?


目前,该项目使用的char8别名使用文字的类型结果u8

// Produces 'char8_t' in C++20, 'char' in anything earlier
using char8 = decltype(u8' ');
Run Code Online (Sandbox Code Playgroud)

但这种方法存在一些问题:

  1. char不保证是无符号的,这使得从数值生成代码点不可移植(例如,char8{129}用 中断char,但不能用 中断char8_t)。

  2. char8char与C++17 中没有区别,后者可能会破坏现有代码,并可能导致错误。

  3. 从第 2 点继续,不可能在 C++17 中重载charchar8处理不同的编码,因为它们不是唯一类型。

如何才能支持在 C++17 和 C++20 模式下运行,同时避免类型差异问题?

Rem*_*eau 2

我建议简单地在 C++20 之前的版本中将您自己的char8_t和类型声明为 alias和. 然后,在任何遇到转换问题的地方,您都可以编写包装函数来在每个版本中适当地处理它们。u8stringunsigned charbasic_string<unsigned char>