M2t*_*2tM 24 c++ stdstring c++20
C ++ 11给我们带来了UTF-8字面量的u8前缀,几年前我认为这很酷,并在代码中添加了以下内容:
std::string myString = u8"?";
Run Code Online (Sandbox Code Playgroud)
一切都很好,但是在C ++ 20中出现了问题,因为u8创建了char8_t *,并且与仅使用char的std :: string不兼容,因此似乎不再可以编译了。
我应该创建一个新的utf8string吗?在C ++ 20世界中,如果我们有更显式的类型与标准std :: string完全不匹配,那么一致的正确方法是什么?
Fab*_*ssi 15
除了@lubgr的答案外,论文char8_t向后兼容修补(P1423)还讨论了如何std::string
使用char8_t
字符数组的几种方法。
基本上,您的想法是可以将u8
char数组转换为“普通” char数组,以获得与C ++ 17相同的行为,在此之前,您必须更加明确一点。本文讨论了执行此操作的各种方法。
适合您的用例的最简单的方法(但并非完全零开销,除非您添加更多的重载)可能是最后一个方法,即引入显式转换函数:
std::string from_u8string(const std::string &s) {
return s;
}
std::string from_u8string(std::string &&s) {
return std::move(s);
}
#if defined(__cpp_lib_char8_t)
std::string from_u8string(const std::u8string &s) {
return std::string(s.begin(), s.end());
}
#endif
Run Code Online (Sandbox Code Playgroud)
lub*_*bgr 14
我应该创建一个新的utf8string吗?
不,它已经在那里。P0482不仅提出char8_t
了命名类型std::basic_string
为的char8_t
字符类型,而且提出了一种新的专业化方法std::u8string
。因此,这与已经编译clang
和libc++
从主干:
const std::u8string str = u8"?";
Run Code Online (Sandbox Code Playgroud)
std::string
从u8
字面意义上进行突破的事实是不幸的。从提案中:
该建议除了保留不赞成使用的接口之外,没有指定任何向后兼容性功能。作者认为这样的功能是必要的,但是这样一组功能将不必要地损害本提案的目标。相反,期望实现将提供选项以启用更细粒度的兼容性功能。
但是我想上面的大多数此类初始化应该是可grep
启用的,或者需要进行一些自动clang
工具修复。
我应该创建一个新的 utf8string 吗?
不,C++20 添加了std::u8string
. 但是,我建议std::string
改用它,因为char8_t
它在标准中的支持很差,并且根本不受任何系统 API 的支持(并且可能永远不会因为兼容性原因而受到支持)。在大多数平台上,普通char
字符串已经是 UTF-8,在带有 MSVC 的 Windows 上,您可以使用/utf-8
它进行编译,这将在主要操作系统上为您提供可移植的 Unicode 支持。
例如,您甚至无法在 C++20 中使用 u8 字符串编写 Hello World 程序(https://godbolt.org/z/E6rvj5):
std::cout << u8"Hello, world!\n"; // won't compile in C++20
Run Code Online (Sandbox Code Playgroud)
在使用 MSVC 和 C++20 之前的 Windows 上,情况更糟,因为 u8 字符串可能会被悄悄损坏。例如:
std::cout << "??????, ???!\n";
Run Code Online (Sandbox Code Playgroud)
将产生有效的 UTF-8 可能会或可能不会显示在控制台中,具体取决于其当前代码页,而
std::cout << u8"??????, ???!\n";
Run Code Online (Sandbox Code Playgroud)
几乎肯定会给你一个无效的结果,例如?????????????????????????, ????????????!
.