![](/img/trans.png)
[英]constexpr std::vector and constexpr std::string in C++20
[英]constexpr std::string in C++20, how does it work?
显然, constexpr std::string尚未添加到GCC的libstdc++中(截至 GCC v11.2)。
这段代码:
#include <iostream>
#include <string>
int main( )
{
constexpr std::string str { "Where is the constexpr std::string support?"};
std::cout << str << '\n';
}
不编译:
time_measure.cpp:37:31: error: the type 'const string' {aka 'const std::__cxx11::basic_string<char>'} of 'constexpr' variable 'str' is not literal
37 | constexpr std::string str { "Where is the constexpr std::string support?"};
| ^~~
In file included from c:\mingw64\include\c++\11.2.0\string:55,
from c:\mingw64\include\c++\11.2.0\bits\locale_classes.h:40,
from c:\mingw64\include\c++\11.2.0\bits\ios_base.h:41,
from c:\mingw64\include\c++\11.2.0\ios:42,
from c:\mingw64\include\c++\11.2.0\ostream:38,
from c:\mingw64\include\c++\11.2.0\iostream:39,
from time_measure.cpp:2:
c:\mingw64\include\c++\11.2.0\bits\basic_string.h:85:11: note: 'std::__cxx11::basic_string<char>' is not literal because:
85 | class basic_string
| ^~~~~~~~~~~~
c:\mingw64\include\c++\11.2.0\bits\basic_string.h:85:11: note: 'std::__cxx11::basic_string<char>' does not have 'constexpr' destructor
我的问题是,当字符串包含超过 16 个char
时(因为 GCC 的 SSO 缓冲区大小为 16),这些字符串将如何在后台工作? 有人可以给我一个简短的解释吗? 一个简单的构造函数会在堆栈上创建字符串 object 并且从不使用动态分配吗?
这段代码:
std::cout << "is_trivially_constructible: "
<< std::boolalpha << std::is_trivially_constructible<const std::string>::value << '\n';
打印这个:
is_trivially_constructible: false
现在在这里使用constexpr
(显然不使用 GCC v11.2 编译):
std::cout << "is_trivially_constructible: "
<< std::boolalpha << std::is_trivially_constructible<constexpr std::string>::value << '\n';
结果会像下面true
吗?
is_trivially_constructible: true
C++20 支持在 constexpr 时间分配,只要分配在时间常数评估结束时完全解除分配。 因此,例如,这个非常愚蠢的例子在 C++20 中是有效的:
constexpr int f() {
int* p = new int(42);
int v = *p;
delete p;
return v;
}
static_assert(f() == 42);
但是,如果您忘记delete p;
在那里,那么f()
不再是一个常量表达式。 不能泄漏 memory。 例如,gcc 拒绝:
<source>:2:24: error: '(f() == 42)' is not a constant expression because allocated storage has not been deallocated
2 | int* p = new int(42);
| ^
回到你的问题, std::string
可以在constexpr
中很好地处理长字符串——正如你所料,通过为其分配 memory 。 但是,C++20 constexpr 规则仍然受到这条规则的限制,即所有分配必须在评估结束时清理。 换句话说,所有分配都必须是瞬态的 - C++ 尚不支持非瞬态 constexpr 分配。
结果,您的原始程序
int main( )
{
constexpr std::string str { "Where is the constexpr std::string support?"};
}
无效,即使 gcc 支持constexpr string
(就像它现在在主干上所做的那样),因为str
需要被销毁。 但这很好:
constexpr int f() {
std::string s = "Where is the constexpr std::string support?";
return s.size();
}
static_assert(f() > 16);
而它不会在 C++17 中编译。
在 C++23 中仍然不支持非瞬态 constexpr 分配。 这是一个令人惊讶的棘手问题。 但是,希望很快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.