为什么在C++std::string中对unicode字符一视同仁

Why are unicode characters treated the same in C++ std::string?

本文关键字:unicode 字符 一视同仁 中对 string C++std 为什么      更新时间:2023-10-16

这里有一个Ideone:http://ideone.com/vjByty.

#include <iostream>
using namespace std;
#include <string>
int main() {
    string s = "u0001u0001";
    cout << s.length() << endl;
    if (s[0] == s[1]) {
        cout << "equaln";
    }
    return 0;
}

我在很多层面上都感到困惑。

当我在C++程序中键入转义的Unicode字符串文字时,这意味着什么?

2个字符不应该用4个字节吗?(假设utf-16)

为什么s的前两个字符(前两个字节)相等?

因此,C++11标准草案规定了以下关于窄字符串文字中的通用字符(emphasis mine forward):

非原始字符串文字中的转义序列和通用字符名与中的含义相同字符文字(2.14.3),除了单引号[…]在窄字符串文字中,通用字符名由于多字节编码,可能映射到多个字符元素

包括以下注释:

窄字符串文字的大小是总数转义序列和其他字符的数量,加上每个字符的至少一个多字节编码通用字符名,加上一个用于终止的"\0"。

上文提及的2.14.3节规定:

通用字符名被翻译为名为的字符。如果没有这样的编码,则通用字符名将被转换为定义的实现编码。

如果我尝试这个例子(看到它直播):

string s = "u0F01u0001";

第一个通用字符确实映射到多个字符。

当我在C++程序中键入转义的Unicode字符串文字时,这意味着什么?

引用标准:

通用字符名被转换为所命名的字符在适当的执行字符集中的编码。如果没有这样的编码,则通用字符名将被转换为实现定义的编码。

通常,执行字符集将是ASCII,其中包含一个值为1的字符。因此u0001将被转换为值为1的单个字符。

如果指定非ASCII字符,如u263A,则每个字符可能会超过一个字节。

2个字符不应该用4个字节吗?(假设utf-16)

如果是UTF-16,是的。但是string不能用UTF-16编码,除非char有16位,而它通常没有。UTF-8是一种更可能的编码方式,其中值高达127的字符(即整个ASCII集)用一个字节进行编码。

为什么s的前两个字符(前两个字节)相等?

根据以上假设,它们都是值为1的字符。