如何在C ++ 20中安全地将const char *转换为const char8_t *?

Rus*_*lan 7 c++ unicode utf-8 c++20

这个答案中,我了解到在C ++ 17中,我们可以std::fstream通过使用UTF-8路径打开std::filesystem::u8path。但是在C ++ 20中,不建议使用此函数,而应该将其传递const char8_t*std::filesystem::path构造函数。

问题来了:尽管我们可以合法地(通过reinterpret_cast)将任何指针转换为const char*,但我们不能向后做:from const char*到eg const char8_t*(这会破坏严格的别名规则)。因此,如果我们有一些外部API返回char文件名的基于UTF-8的表示形式(例如,使用C语言编写的库),则无法安全地将指针转换为char8_t基于文件的指针。

那么,我们应该如何将这种char基于UTF-8字符串char8_t的视图转换为基于它们的UTF-8字符串?

Tom*_*ann 5

免责声明:我是P0482提案的作者,该提案引入char8_t并弃用了u8path.

你的观察是正确的;不允许使用它reinterpret_cast来生成char8_t指向对象序列的指针char这将在/sf/answers/4021759941/进一步讨论。

尽管std::filesystem::u8path它在 C++20 中已被弃用,但目前还没有计划立即删除它;您可以继续使用它。此外,P1423纠正了P0482中更改的意外结果,并允许在 C++20 中使用char和 的范围来调用它char8_t。据我所知,没有实现者将其注释std::filesystem::u8path为已弃用(我不知道是否有计划这样做)。

没有(格式良好的)方法来生成char8_t基于指针的序列视图char。可以编写一个范围/迭代器适配器,在内部将各个char值转换为char8_t迭代器取消引用。这样的适配器可以满足 C++17 和 C++20 随机访问迭代器对不可变迭代器的要求(它不能满足可变迭代器的要求,因为取消引用操作无法提供左值,也不能满足连续迭代器的要求)。这样的适配器足以调用std::filesystem::path接受范围的构造函数。嗯,这可能是一个足够有用的适配器,可以添加到https://github.com/tahonermann/char8_t-remediation

当然,查看基础char数据的另一种方法是复制它,但我可以理解为什么这样做可能被认为是不可取的(我们在使用时已经倾向于进行大量复制std::filesystem::path)。

  • `std::u8string_view` 应该是这个适配器。它是不可变的,其最初的目的是使用户不必关心底层的字符串存储。为什么我们不能拥有美好的东西:(? (3认同)

Som*_*ude 2

这个字符类型参考关于char8_t

它具有与 和 相同的大小、符号和对齐方式unsigned char(因此,与char和具有相同的大小和对齐方式signed char),但它是一种不同的类型。

因为它是一种独特的类型,所以您无法在不破坏严格别名的情况const char*下进行转换const char8_t*。但出于所有实际目的,sincechar8_t基本上是unsigned char您可以用来reinterpret_cast转换指针的。这是错误的,但会起作用。

为了获得正确的正确性,要么使用char8_t开始,要么将原始字符复制到char8_t缓冲区(或std::u8string)。