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字符串?
免责声明:我是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)。
从这个字符类型参考关于char8_t:
它具有与 和 相同的大小、符号和对齐方式
unsigned char(因此,与char和具有相同的大小和对齐方式signed char),但它是一种不同的类型。
因为它是一种独特的类型,所以您无法在不破坏严格别名的情况const char*下进行转换const char8_t*。但出于所有实际目的,sincechar8_t基本上是unsigned char您可以用来reinterpret_cast转换指针的。这是错误的,但会起作用。
为了获得正确的正确性,要么使用char8_t开始,要么将原始字符复制到char8_t缓冲区(或std::u8string)。