C++ C和x2B之前的char8_t/UTF8 chars情况+;17、可怜的人在做什么?
我一直在阅读有关即将推出的“utf8”字符类型C++ C和x2B之前的char8_t/UTF8 chars情况+;17、可怜的人在做什么?,c++,utf-8,char,C++,Utf 8,Char,我一直在阅读有关即将推出的“utf8”字符类型char8_t及其在C++20中对应的字符串类型的链接,在某种程度上可以说,是时候了。而且,这是一个混乱 请随时纠正我的错误: C++和任何标准都无法指定源代码具有给定的文本编码(比如Python的#编码:…元数据),也无法指定它可以编译成什么标准(比如说#!/bin/env g++-std=C++14) 在C++11之前,也没有办法指定任何给定的字符串文字将具有给定的编码-如果需要,编译器可以自由地将UTF8字符串文字重新分析为UTF16甚至EB
char8_t
及其在C++20中对应的字符串类型的链接,在某种程度上可以说,是时候了。而且,这是一个混乱
请随时纠正我的错误:
- C++和任何标准都无法指定源代码具有给定的文本编码(比如Python的
元数据),也无法指定它可以编译成什么标准(比如说#编码:…
)#!/bin/env g++-std=C++14
- 在C++11之前,也没有办法指定任何给定的字符串文字将具有给定的编码-如果需要,编译器可以自由地将UTF8字符串文字重新分析为UTF16甚至EBCDIC李>
- C++11引入了
和u16“text”
以及相关的字符类型来生成UTF16和UTF32编码的文本,但没有提供字符串或流工具来处理它们,因此它们基本上是无用的u32“text”
- C++11还引入了
来生成UTF8编码的字符串。。。 但是甚至没有引入适当的UTF8字符类型或字符串类型(这就是C++20中的u8“text”
的目的),因此它的使用甚至比上面的更少char8_t
- 正因为如此,当
最终被引入时,它杀死了许多原本打算有效的代码,到目前为止,寻求的一些补救措施包括char8\t
- 即使是这样,也没有现成的工具(如:与代码< >代码>不一样的CRAP层接口)来检查、转换(在同一个字符串中)或在C++中转换(复制字符串类型)文本编码。甚至codecvt似乎也被删除了
-
<>代码> U8“文本”< /C> >,否则延迟导入<代码> u8< /代码>?,为什么C++不添加<代码> CHAR8GYT <代码>?
- 或者,为什么不像C++20中的
那样引入另一个非中断前缀char8\t
,而不是引入大范围中断更改?我认为TPTB讨厌破坏变化,甚至更讨厌破坏最简单的情况:c8“text”
cout我是和
论文的作者 而且,这是一个混乱 我完全同意。正在努力改进所有与Unicode和文本相关的东西,但我们必须从接近地面的地方开始,所以这需要一段时间 如果您还没有看到,下面链接的存储库提供了一些实用程序,用于编写在C++17和C++20中工作的代码char8\t
和“text”
,2)启用区分依赖于区域设置的文本和UTF-8文本(从类型系统强制执行),3)确保UTF-8代码单元使用无符号类型,以及4)避免u8“text”
类型别名惩罚。这就是我们为C++20所做的全部工作(标准化不是一个快速的过程) 正因为如此,当char8_t最终引入时,它杀死了许多原本打算有效的代码,到目前为止,寻求的一些补救措施包括完全禁用char8_t行为 正确,char
被认为是一个突破性的变化;不可掉以轻心的事情。在这种情况下,它被认为是可以接受的,因为1)代码搜索发现很少使用char8\u t
字符和字符串文本,2)用于解决向后兼容性的选项u8
// this is here basically only for type-distinctiveness class char8_t { unsigned char value; public: non_explicit constexpr char8_t (unsigned char ch = 0x00) noexcept; operator unsigned char () const noexcept; // implement all operators to mirror operations on unsigned char }; // public adapter jic friend unsigned char to_char (char8_t); // note we're *not* using our new char-type here namespace std { typedef std::basic_string<unsigned char> u8string; } // unsure if these two would actually be needed // (couldn't make a compelling case so far, // even testing with Windows's broken conhost) namespace std { basic_istream<char8_t> u8cin; basic_ostream<char8_t> u8cout; } // we work up operator<<, operator>> and string conversion from there // adding utf8-validity checks where needed std::ostream& operator<< (std::ostream&, std::u8string const&); std::istream& operator>> (std::istream&, std::u8string&); // likely a macro; we'll see #define u8c(ch) static_cast<char8_t>(ch) // char8_t ch = u8c('x'); // very likely not a macro pre-C++20; can't skip utf-8 validity check on [2]? u8string u8s (char8_t const* str); // [1], likely trivial u8string u8s (char const* str); // [2], non-trivial // C++20 and up #define u8s(str) u8##str // or something; not sure // end result: // no, I can't even think how would one spell this: u8string text = u8s("H€łlo Ẅørλd"); // this wouldn't work without refactoring u8string into a full specialization, // to add the required constructor, but doing so is a PITA because // the basic_string interface is YAIM (yet another infamous mess): u8string text = u8"H€łlo Ẅørλd";
typedef std::basic_string<unsigned char> u8string; u8string u8s(U8("text"));