Vla*_*lad 33 c++ stdstring visual-c++ constexpr c++20
constexpr std::string尝试创建and对象时出现奇怪的编译器错误std::vector:
#include <vector>
#include <string>
int main()
{
constexpr std::string cs{ "hello" };
constexpr std::vector cv{ 1, 2, 3 };
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨“表达式必须具有常量值”:
我错过了什么吗?我使用的是最新的 Microsoft Visual Studio 2019 版本:16.11.4,并且参考(https://en.cppreference.com/w/cpp/compiler_support)指出constexpr此编译器版本支持字符串和向量:
我也尝试过constexpr std::array,它确实有效。该问题是否与向量相关的动态内存分配有关?
Bar*_*rry 44
您的程序实际上格式不正确,尽管该错误可能很难理解。constexprC++20 中的分配支持是有限的 - 您只能进行临时分配。也就是说,分配必须在持续评估结束时完全解除分配。
所以你不能这样写:
int main() {
constexpr std::vector<int> v = {1, 2, 3};
}
Run Code Online (Sandbox Code Playgroud)
因为v的分配是持续的 - 它是非暂时性的。这就是错误告诉您的内容:
<source>(6): error C2131: expression did not evaluate to a constant
<source>(6): note: (sub-)object points to memory which was heap allocated during constant evaluation
Run Code Online (Sandbox Code Playgroud)
v不能是常量,因为它仍然保留堆分配,并且不允许这样做。
但你可以这样写:
<source>(6): error C2131: expression did not evaluate to a constant
<source>(6): note: (sub-)object points to memory which was heap allocated during constant evaluation
Run Code Online (Sandbox Code Playgroud)
这里,v的分配是暂时的——返回时内存被释放f()。但我们仍然可以使用a std::vectorwhile constexpr。
正如 @barry 所解释的,您无法创建需要动态分配且在运行时仍然可用的变量。我相信这是通过以下排除来解释的:
表达式 E 是核心常量表达式,除非对 E 的求值遵循抽象机 ([intro.execution]) 的规则,将求值以下其中一项:
https://eel.is/c++draft/expr.const#5.17
new 表达式 ([expr.new]),除非所选分配函数是可替换的全局分配函数 ([new.delete.single]、[new.delete.array]),并且分配的存储空间在E;
尽管如此,您仍然可以利用这些新功能做出令人惊奇的事情。例如连接字符串:
constexpr std::string join(std::vector<std::string> vec, char delimiter) {
std::string result = std::accumulate(std::next(vec.begin()), vec.end(),
vec[0],
[&delimiter](const std::string& a, const std::string& b) {
return a + delimiter + b;
});
return result;
}
static_assert(join({ "one", "two", "three" }, ';') == "one;two;three"sv);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7484 次 |
| 最近记录: |