我一直在阅读链接作为这个问题,当然这个问题是关于char8_t在 C++20 中为即将到来的“utf8”字符类型及其相应的字符串类型做准备的问题,并且可以说,在某种程度上,是时候了。还有就是一团糟。
请随时纠正我的错误:
# encoding:...元数据),也无法将其编译成什么标准(如 say #!/bin/env g++ -std=c++14)。u16"text"和u32"text"相关的 char 类型来生成 UTF16 和 UTF32 编码的文本,但没有提供字符串或流工具来处理它们,所以它们基本上没用。u8"text"用于生成 UTF8 编码的字符串......但它甚至没有引入正确的 UTF8 字符类型或字符串类型(这char8_t就是 C++20 中的意图?),所以它甚至比以上。char8_t是终于出台,它杀死很多原打算是有效的,到目前为止,一些调控措施的要求包括代码完全禁用char8_t行为。<random>)来检查、转换(在同一字符串内)或转换(跨字符串类型复制)C++ 中的文本编码。甚至 codecvt 似乎也已被删除。鉴于上述所有情况,我有一些关于为什么我们处于这种奇怪状态以及它是否会变得更好的问题。从历史上看,Unicode 支持一直是 C++ 的最低点之一。
同样,我想知道整个概念的穷人模拟有多大用处(免责声明:我是cxxomfort 的维护者,我已经向后移植了很多东西。工作需要:办公室最新的MSVC 目标是 MSVC 2012)。
char8_t在u8"text"引入的适当时间添加或以其他方式延迟引入u8?c8"text",char8_t而不是引入范围广泛的破坏性更改?我认为 TPTB讨厌破坏性更改,甚至更讨厌破坏最简单情况的东西:cout<< prefix"hello world".char8_t打算在功能上成为(更接近于)unsigned char或 的别名char?typedef std::basic_string<unsigned char> u8string可行的仿真策略?在编写我自己的之前,是否有可用的反向移植/参考实现?回复:char8_t作为unsigned char,这或多或少是我在伪代码方面的看法:
// 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";
Run Code Online (Sandbox Code Playgroud)
我已经将这个 C++ 标记为一般性,但这更多的是关于 C++20 之前的标准的(价值)实现。更重要的是,我不是在寻找“完美”的解决方案或理由;鉴于上下文,穷人的已经绰绰有余。
还有就是一团糟。
我完全同意。 SG16正在努力改进与 Unicode 和文本相关的所有内容,但我们必须从接近地面开始,因此需要一段时间。
如果您还没有看到它,下面链接的存储库提供了一些用于编写可在 C++17 和 C++20 中运行的代码的实用程序。
C++,任何标准,都无法指定源代码具有给定的文本编码(类似于 Python 的 # encoding:... 元数据),也无法将其编译成什么标准(比如 #!/bin/env g++ -std=c++14)。
这是正确的,但并非没有先例。IBM 的 xlC 编译器支持一个#pragma filetag指令,其行为类似于 Python 的编码声明。我开始写一篇探索这个空间的论文,并希望将其提交给布拉格会议,但没有及时完成。我希望将其提交给瓦尔纳会议(6 月)。
在 C++11 之前,也没有办法指定任何给定的字符串文字将具有给定的编码 - 编译器可以自由地将 UTF8 字符串文字重新解析为 UTF16 甚至 EBCDIC,如果需要的话。
正确,在 C++20 和采用P1041之前,这在技术上一直适用于char16_t和char32_t字符串文字。但请注意,没有进行重新分析。在转换阶段 1 中,源代码内容被转换为编译器的内部编码,然后在转换阶段 5 中,字符和字符串文字被转换为适当的执行字符集的编码。
C++11 引入了 u16"text" 和 u32"text" 以及相关的 char 类型来生成 UTF16 和 UTF32 编码的文本,但没有提供字符串或流工具来处理它们,所以它们基本上没用。
正确的。 P1629是我们希望为 C++23 完成的更重要的更改之一。目标是提供文本编码器、解码器和转码器,以促进在代码单元和代码点级别处理文本。我们还将为枚举字形集群提供支持。
C++11 还引入了 u8"text" 来生成 UTF8 编码的字符串......但甚至没有引入正确的 UTF8 字符类型或字符串类型(这就是 char8_t 在 C++20 中的意图?),所以它甚至比上面的更没用。
正确的。用于C ++ 20的目标是:1)使能分化"text"和u8"text"在类型系统,2)使分离区域设置依赖性和UTF-8文本(从类型系统执行),3)确保使用无符号类型的用于UTF- 8 个代码单元,以及 4) 避免char类型别名惩罚。这就是我们为 C++20 完成的所有时间(标准化不是一个快速的过程)。
正因为如此,当 char8_t 最终被引入时,它会杀死许多原本应该有效的代码,到目前为止,寻求的一些补救措施包括完全禁用 char8_t 行为。
正确,char8_t被提议作为一个突破性的改变;不能掉以轻心的事情。在这种情况下,它被认为是可以接受的,因为 1) 代码搜索发现很少使用u8字符和字符串文字,2) P1423 中讨论的解决向后兼容性问题的选项被认为是足够的,以及 3) 一个不间断的提案将添加语言的长期包袱,收获甚微。
即便如此,也没有现成的工具(例如:与 不同的垃圾层接口)来检查、转换(在同一字符串内)或转换(跨字符串类型复制)C++ 中的文本编码。甚至 codecvt 似乎也已被删除。
正确的。我们将努力改善这种情况,但这需要时间。 codecvt还没有被丢弃(还);的<codecvt>报头和各种UTF转换器在C ++ 17被弃用。 std::codecvt受到性能和可用性问题的影响,因此不被认为是我们可以继续构建的东西。我们认为P1629是一个更好的方向。
为什么在引入 u8"text" 时 C++ 没有在适当的时候添加 char8_t 或以其他方式延迟引入 u8?
我询问了参与最初工作的 C++ 委员会成员之一。他告诉我,他问当时从事 Unicode 工作的人是否应该添加新类型,他们的回答是,“嗯,我们不需要它”。
或者,为什么没有在 C++20 中用 char8_t 引入另一个像 c8"text" 这样的非破坏性前缀,而不是引入广泛的破坏性变化?我认为 TPTB 讨厌破坏性更改,甚至更讨厌破坏最简单可能情况的东西:cout<< prefix"hello world"。
考虑了不同的前缀,有一次我简要地赞成这种方法。然而,如前所述,这会给我们留下两种拼写 UTF-8 文字和相关历史包袱的方式。从长远来看,人们认为只要我们有合理的方法来减轻破坏,破坏性的变化就会带来更多的好处。
关于那个简单的测试用例,花点时间思考一下该代码应该做什么。然后去阅读这个:char8_t * 的 printf() 格式字符是什么?.
char8_t 是否打算在功能上(更接近) unsigned char 或 char 的别名?
char8_t有意且明确地不是别名(因为它具有负面的性能影响)但被指定为具有与unsigned char. unsigned charover的原因char是为了避免像u8'\x80' < 0曾经评估为真这样的表达式(char今天可能是也可能不是这种情况)。
如果是前者,是否正在寻找一种可行的模拟策略,例如:typedef std::basic_string u8string?在编写我自己的之前,是否有可用的反向移植/参考实现?
我不会评论这种方法是否是一个好主意,但之前已经这样做了。比如EASTL就有这样一个typedef(那个项目还提供了一个定义char8_t是否原生类型不可用)
我们在 C++17 或更低版本中最接近将文本标记为(打算是)UTF-8仅用于存储的方法是什么?
我认为这个问题没有一个正确的答案。我见过项目通过类使用unsigned char或提供char8_t类似的类型。
关于您的伪代码,对前面提到的char8_t-remediation 存储库中的代码进行一些调整以提供unsigned char类型而不是char应该使如下代码能够工作。见的定义_as_char用户定义的文字和U8宏。
typedef std::basic_string<unsigned char> u8string;
u8string u8s(U8("text"));
Run Code Online (Sandbox Code Playgroud)