如何在 C++20 中安全地将常量字符* 转换为常量 char8_t*?
How to safely convert const char* to const char8_t* in C++20?
从这个答案中我了解到,在 C++17 中,我们可以通过std::filesystem::u8path
使用 UTF-8 路径打开std::fstream
。但是在 C++20 中,这个函数被弃用了,我们应该const char8_t*
传递给std::filesystem::path
构造函数。
问题来了:虽然我们可以合法地转换(通过reinterpret_cast
(任何指向const char*
的指针,但我们不能向后:从const char*
到例如const char8_t*
(它会破坏严格的别名规则(。因此,如果我们有一些外部 API 返回文件名的基于char
的 UTF-8 表示形式(例如,来自用 C 编写的库(,我们无法安全地将指针转换为基于char8_t
的指针。
那么,我们应该如何将这种基于char
UTF-8 字符串的视图转换为基于char8_t
的视图呢?
免责声明:我是 P0482 提案的作者,该提案引入了char8_t
并弃用了u8path
。
您的观察是正确的;不允许使用reinterpret_cast
来生成指向char
对象序列的char8_t
指针。 这将在 https://stackoverflow.com/a/57453713/11634221 中进一步讨论。
虽然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*
。但出于所有实际目的,由于char8_t
基本上是一个unsigned char
您可以使用reinterpret_cast
来转换指针。这是错误的,但会起作用。
为了正确起见,请使用char8_t
开头,或将原始字符复制到char8_t
缓冲区(或std::u8string
(。
- 为什么下面带有非常量转换函数的代码没有歧义?
- 如何将变量内容常量转换为 std::array 的大小?
- 将结构C++成员从非常量转换为常量
- 意外 (IMO) 常量转换警告
- 警告:ISO C++禁止将字符串常量转换为'char*' [-Wwrite-strings]
- 为什么无法将常量 X 转换为 X &?
- 重载常量和非常量转换运算符返回数组类型时出现 MSVC 错误 C2593
- 将字符串常量转换为char
- 警告:ISO C++禁止将静态“constexpr char*”数据成员的字符串常量转换为“char*”
- 错误C2662无法从常量转换为引用
- 常量转换运算符的行为
- 如何在 C 中将多字符常量转换为整数
- 从字符串常量转换,c++ 中的指针
- 从字符串常量转换为字符*
- 在这里做常量转换安全吗
- boost序列化错误C4308:负整数常量转换为无符号类型
- 不赞成从字符串常量转换为“char*”[-Wwrite strings]
- C++非常量到常量转换编译错误
- C++-不赞成在第三方标头中从字符串常量转换为“char*”
- 空指针常量转换为右值