std::u8string与std::string有何不同?
how std::u8string will be different from std::string?
如果我有一个字符串:
std::string s = u8"你好";
而在C++20,
std::u8string s = u8"你好";
std::u8string
与std::string
有何不同?
由于u8string
和string
之间的区别在于一个在char8_t
上模板化,另一个在char
上模板化,真正的问题是使用基于char8_t
的字符串与使用基于 的字符串有什么区别。 基于char
的字符串。
它实际上归结为:基于类型的编码。
任何基于char
的字符串(char*
、char[]
、string
等)都可以用UTF-8编码。但话又说回来,它可能不会。您可以在假设每个等效项char*
都将采用 UTF-8 编码的情况下开发代码。您可以在每个字符串文本前面编写一个u8
和/或以其他方式确保它们已正确编码。但:
-
其他人的代码可能不同意。因此,您不能使用任何可能返回不使用 UTF-8 编码
char*
的库。 -
你可能会不小心违反你自己的戒律。毕竟,
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 编码的此类型的字符串,则认为这是用户的错误/背信弃义并不是没有道理的,这是违反合同的。
我们可以看到C++如何受到 UTF-8 缺乏类似的、基于类型的设施的影响。考虑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,而不是任意字节数组。
- Python中的for循环与C++有何不同
- 在C++中释放内存期间,迭代器与指针有何不同
- -fvisibility-inline-hidden 与 gcc 中的 -fvisibility=hidden 有何不同
- 重载std::映射不同的密钥类型
- 收益率和回报有何不同?
- 覆盖私有功能,它与受保护功能有何不同?
- 无论代码长度如何,以下代码的内存要求有何不同?
- stl::unordered_map 和 stl::vector 的销毁有何不同
- C++ 友元函数在内存位置上有何不同?
- 如何声明一个 std::用不同值内联初始化的结构数组
- C 是否具有接口类概念,如果它在那里,那么它与Java接口类别有何不同
- std::u8string与std::string有何不同?
- 两种类型转换有何不同?
- C++ thread_local具有与 std::thread 不同的线程库
- std::chrono 不同的结果 - 固定的时间步长循环
- 这个语句到底是什么意思 stack<int, list<int> > 它与 stack 有何不同<int>?
- 英特尔®事务同步扩展新指令 (TSX-NI) 与英特尔 TSX 有何不同?
- 指向成员函数的指针与指向数据成员的指针有何不同
- 字符 * 和字符串在C++中有何不同?(在描述中编写代码)
- C++11: boost::make_tuple 与 std::make_tuple 有何不同?