use*_*241 8 c++ string unicode c++20
如果我有一个字符串:
std::string s = u8"??";
Run Code Online (Sandbox Code Playgroud)
在C ++ 20中
std::u8string s = u8"??";
Run Code Online (Sandbox Code Playgroud)
有何std::u8string
不同std::string
?
由于之间的差别u8string
,并string
是一个模板上char8_t
,另一个在char
中,真正的问题是,什么是两者的区别char8_t
为基础的弦与char
基于字符串。
真正归结为:基于类型的编码。
任何char
基于字符串(char*
,char[]
,string
等)可以以UTF-8编码。但是话又说回来,可能不会。您可以在假设所有char*
等效项都将以UTF-8编码的前提下开发代码。您可以u8
在每个字符串文字前写一个和/或以其他方式确保对它们进行正确编码。但:
其他人的代码可能不同意。因此,您不能使用任何可能返回char*
s且未使用UTF-8编码的库。
您可能不小心违反了自己的戒律。毕竟,char not_utf8[] = "??";
有条件地支持C ++。char[]
不管是什么,其编码将是编译器的窄编码。在某些编译器上可能是UTF-8,在其他编译器上可能是其他。
您不能告诉其他人的代码(甚至团队中的其他人)您正在做的事情。也就是说,您的API无法声明某个特定内容char*
是UTF-8编码的。这必须是用户认为或在文档中已经阅读过的内容,而不是他们在代码中看到的内容。
请注意,对于UTF-16或UTF-32的用户,这些问题都不存在。如果使用char16_t
基于字符串,则所有这些问题都会消失。如果其他人的代码返回一个char16_t
字符串,则说明他们在做什么。如果他们返回其他内容,那么您就会知道这些内容可能不是UTF-16。您基于UTF-16的代码可以与其互操作。如果您编写一个返回char16_t
基于字符串的API,则使用该代码的每个人都可以从该字符串的类型中看到其编码方式。并且这肯定是编译错误:`char16_t not_utf16 [] =“ ??”;
现在是的,不能保证所有这些事情。任何特定的char16_t
字符串都可以包含任何值,即使那些对于UTF-16非法的值也是如此。但是char16_t
代表默认假设为特定编码的类型。鉴于此,如果您提供的字符串不是UTF-16编码的类型,则认为这是用户的错误/专横是违反合同的,这是不合理的。
我们可以看到缺少类似的基于类型的UTF-8设施对C ++的影响。考虑一下filesystem::path
。它可以采用任何Unicode编码的字符串。对于UTF-16 / 32,path
的构造函数采用char16/32_t
基于字符串。但是您不能将UTF-8字符串传递给path
的构造函数;该char
系构造假定编码是实现定义的窄编码,而不是UTF-8。因此,您必须使用filesystem::u8path
,这是一个单独的函数,该函数返回一个path
由UTF-8编码的字符串构造的。
更糟糕的是,如果您尝试将基于UTF-8编码char
的字符串传递给path
的构造函数...它会很好地编译。尽管充其量是不可移植的,但它似乎还是可以工作的。
char8_t
和所有类似的附件的u8string
存在,是为了允许UTF-8用户获得与其他UTF编码相同的功能。在C ++ 20中,filesystem::path
将char8_t
基于基的字符串重载,并且u8path
将变得过时。
而且,作为一项额外的好处,char8_t
它周围没有特殊的别名语言。因此,采用char8_t
基于字符串的API 肯定是采用字符数组而不是任意字节数组的API。
归档时间: |
|
查看次数: |
380 次 |
最近记录: |