当年我们写字符串。
很少有人认真区分编码。
char* 就是字符串。
能显示就行。
直到你做国际化。
或者线上突然出现乱码。
你才发现。
“编码”这事。
其实一直在。
当年:UTF-8 只是一个约定
你写 u8"你好"。
你心里想的是。
“这是 UTF-8”。
但类型上。
它还是 const char*。
你可以随便传给任何吃 const char* 的 API。
编译器也不会拦你。
线上啪一下:你以为你在传 UTF-8,其实你在传一段字节
很多库函数。
只是把 char* 当字节数组。
它并不懂 UTF-8。
你传进去。
它也不会提醒你。
于是 bug 会变成。
运行时才暴露。
而且暴露方式很丑。
乱码。
截断。
或者长度计算错。
C++20:char8_t
C++20 说。
UTF-8 字面量不该再伪装成 char。
它应该有自己的类型。
所以 u8"hi" 的类型变成了 const char8_t*。
你会立刻遇到的编译错误
你有个老函数。
void log_text(const char* s);
你以前这么调用。
log_text(u8"hello");
C++20 下。
它会编译不过。
因为 const char8_t* 不能隐式转成 const char*。
那我该怎么办
最正确的做法是。
把接口说清楚。
如果你真的想要 UTF-8。
那你就让接口吃 const char8_t*。
void log_utf8(const char8_t* s);
如果你只是要“字节串”。
那你就别用 u8 字面量。
用普通字符串字面量。
你刚学 C++ 会卡:那我能不能强转
能。
但你要知道自己在干嘛。
log_text(reinterpret_cast<const char*>(u8"hello"));
这行代码的意思是。
“我不在乎编码语义,我只把它当字节”。
你要是写这句。
就别再指望编译器帮你兜底。
关键结论
char8_t 不是为了折磨你。
它是为了让“UTF-8”从约定变成类型。
小结
编码问题。
一直都在。
C++20 只是把它摊开。
让你不得不把接口说清楚。