我之前在 Why `constexpr` specifier is not allowed for non-empty `std::vector`? 中问过一个问题,找到答案后,我在这里还有另一个问题。
我测试发现,在一个
constexpr
函数中动态分配内存并在另一个 constexpr
函数中释放内存(通过 new
和 delete
)是有效的,因此 constexpr
子例程不会引入新的内存上下文:
constexpr int* bar() {
return new int{2};
}
constexpr int foo() {
auto ptr = bar();
int val = *ptr;
delete ptr;
return val;
}
constexpr int i = foo(); // OK
然后我又遇到一个问题,
constexpr
需要什么条件才能开始一个新的上下文?
在常量表达式上下文中(如在
consteval
函数中),为什么 constexpr std::vector<int>
将启动一个新的常量表达式上下文(这使得声明无效,因为通过 new
分配的内存将逃逸此上下文)而 std::vector<int>
不在新的常量表达式上下文中分配内存?
我是
constexpr
和C++20的新学习者,请指出我是否得到了错误的假设或提出了错误的问题。
constexpr 将启动新上下文的条件是什么?
作为一个常数表达式。
constexpr
或constinit
变量的初始值设定项是常量表达式。模板参数的初始化器是一个常量表达式。 if constexpr
中的表达式是常量表达式。这些表达式开始常量表达式上下文。 调用
constexpr
函数不是常量表达式。在计算常量表达式时调用
constexpr
函数发生在常量表达式上下文中,但它本身并不是上下文。调用
consteval
函数本身并不是常量表达式上下文,但除非您已经在常量表达式上下文中,否则不允许调用该函数。