为什么`constexpr向量`不允许在`consteval`函数中分配?

Wak*_*ker 6 c++ constexpr c++20

第四次编辑:原始问题标题是:

为什么constexpr说明符不允许非空std::vector

正如 @Barry 指出的,这个标题与C++20 constexpr vector and string not working重复。但我的问题描述有所不同:我constexpr vectorconstevalfunction而不是正常的运行时 function 或constexprfunction中分配。

据我所知,在编译时计算期间,只允许瞬时分配,正如 @Barry 在链接问题中回答的那样。

我感到困惑的是:对于consteval功能:

  1. 它的任何局部变量将在返回后被释放
  2. 它只在编译时返回,因为它只会在编译时被调用
  3. soconstexpr vector作为局部变量,将在编译时释放
  4. 那么为什么不允许呢?

我在下面的其他编辑回答了这个困惑。

-----------------以下是原问题描述----------

为什么下面的代码不能编译:

consteval int foo() {
  constexpr std::vector<int> vec{1};
  return vec[0];
}
Run Code Online (Sandbox Code Playgroud)

据我所知,只要分配和释放都发生在编译时,就可以在编译时使用 和std::vectorstd::string如果我删除constexpr说明符,该代码将编译。

但是添加constexpr仍然不违反这个规则,对吗?为什么不允许?

使用 gcc 13 编译时出现此错误,但我不明白:

/opt/compiler-explorer/gcc-13.1.0/include/c++/13.1.0/bits/allocator.h:195:52: error:
'std::vector<int>(std::initializer_list<int>{((const int*)(& const int [1]{1})), 1}, std::allocator<int>())' is not a constant expression because it refers to a result of 'operator new'
  195 |             return static_cast<_Tp*>(::operator new(__n));
      |                  
Run Code Online (Sandbox Code Playgroud)

编辑:我的问题与任何其他问题都不重复。std::vector 上只有一个重复的constexpr 说明符不起作用,但关于为什么constexpr不允许的答案是错误的:它指出“编译时std::vector应该在编译时分配和释放,因此不允许” ,但是上面的代码并没有违反这个规则。

第二次编辑:感谢@user4581301 和@chris 的回答。我发现我对一条规则的理解是错误的:

错误new:如果在编译时分配的内存也在编译时delete分配,那就没问题了。

正确:在编译时,通过分配的内存new必须位于相同的常量表达式上下文delete中。

我的问题的答案是,它将constexpr vector<int>引入一个新的常量表达式上下文,而vector<int>不会。

第三次编辑`constexpr` 将启动新的常量表达式上下文的条件是什么?