cppreference提到,如果初始化包含初始化部分,则在 C++20 中使用 constinit 时程序格式不正确。
我只是想知道为什么下面的代码可以编译:
constinit std::string str = "Hello";
由于std::string
该类涉及用于存储字符的动态内存分配,因此这似乎是矛盾的。由于动态部分,这不应该被禁止吗?
尝试使用标志进行编译-std=C++20
,程序编译正常,但事实并非如此。
3
最佳答案
2
std::string
如果字符串足够短,常见的实现就不会在堆上分配(这称为“短字符串优化”或“SSO”)。
由于 SSO 中可容纳的字符的确切数量(如果有)取决于实现,因此您可能不应该依赖它,或者至少应该研究三大标准库如何处理这个问题。
|
这个答案是对@HolyBlackCat答案的补充。
正如那里解释的那样,您成功编译的原因如下:
constinit std::string str = "Hello";
是由于短字符串优化(SSO)。
这两个演示证明了这一点:
- 上面这行代码可以在所有 3 个主流编译器上编译。
参见。 - 将字符串的大小增加到 SSO 无法处理的范围(
"Hello1234567890123456789012345678901234567890"
在本例中),会导致所有 3 个编译器出现编译错误
(例如 gcc 问题error: 'constinit' variable 'str' does not have a constant initializer
:)。
参见。
请注意,SSO 支持的具体长度取决于实现。
在上面的演示中,我只是增加了长度,直到失败。SSO 的最大长度可能会在未来版本中发生变化。
|
–
–
–
|