如果我有一个字符串:
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
和/或以其他方式确保它们已正确编码。但:
char*
的库。 char not_utf8[] = "你好";
是有条件支持的C++。该char[]
的编码将是编译器的窄编码...无论是什么。在某些编译器上可能是UTF-8,在其他编译器上可能是其他。 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编码,则认为这是用户的错误/行为是不违反契约(Contract)的,这是不合理的。我们可以看到缺少类似的基于类型的UTF-8设施对C++的影响。考虑
filesystem::path
。它可以采用任何Unicode编码的字符串。对于UTF-16/32,path
的构造函数采用基于char16/32_t
的字符串。但是您不能将UTF-8字符串传递给path
的构造函数;基于char
的构造函数假定该编码是实现定义的窄编码,而不是UTF-8。因此,您必须使用filesystem::u8path
,这是一个单独的函数,该函数返回由utf-8编码的字符串构造的path
。更糟糕的是,如果您尝试将基于UTF-8编码的基于
char
的字符串传递给path
的构造函数...它会很好地编译。尽管充其量是不可移植的,但它似乎还是可以工作的。char8_t
及其所有附件(如u8string
)的存在是为了允许UTF-8用户获得与其他UTF编码相同的功能。在C++ 20中,filesystem::path
将获得基于char8_t
的字符串和 u8path
will become obsolete.的重载。而且,作为额外的好处,
char8_t
周围没有特殊的别名语言。因此,采用基于char8_t
的字符串的API当然是采用字符数组而不是任意字节数组的API。
关于c++ - std::u8string与std::string有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56420790/