C++20 P0784R7 非瞬态分配与 P1004R2 constexpr 相比太脆弱 std::vector

C++20 P0784R7 Non-transient allocation too brittle vs. P1004R2 constexpr std::vector

我想在 C++20 中创建一个广泛的 constexpr 数据存储库。数以万计的本机 C++ 对象加载为“文本段”,即请求分页到进程中并在实例之间共享(生成代码)。

对象相互引用,需要通过各种属性进行索引、交叉引用等,所有这些都希望在编译时完成。这需要 constexpr(关联)容器,但不能使用模板化(按大小、哈希大小等)容器来完成,因为一切都需要保持多态性。

首先这似乎是不可能的,因为 C++20 P0784R7 说非瞬态分配太脆弱,即动态分配的内存不允许从 constexpr 评估中泄漏。

同时C++20P1004R2说要支持constexpr std::vector。在后一篇论文中,我看到了所有成员,包括标记为 constexpr 的修改成员。因此,除非我遗漏了什么,否则我可以在 constexpr 评估中向 std::vectors 添加元素(编译器还不支持它,所以我不能尝试)。

// 21.3.11.5, modifiers
template<class... Args> constexpr reference emplace_back(Args&&... args);
constexpr void push_back(const T& x);
constexpr void push_back(T&& x);
...

但是为什么我不能围绕 std::vector<T> 构建一个 allocator<T> 并且仍然有非瞬态分配?这两种能力不是“计算上等价的”即constexpr std::vector需要实现非瞬时分配,因此它也可以提供它?

编译器什么时候最终支持它? ...或者这种疑似矛盾甚至是延迟的原因?

你对瞬态分配有误解。瞬态分配是 完全 在持续评估中存在的分配。例如:

constexpr std::size_t summation(std::vector<unsigned int> const &vi)
{
  std::size_t ret = 0;
  for(auto i : vi)
    ret += i;
  return ret;
}

constexpr auto sum = summation({20, 44, 98});

summation 的调用中,最终输入源(braced-init-list 及其值)在编译时完全已知。是的,有一个 vector,但这 完全 存在于常量表达式求值中。 vector 对象用于计算常量值,但 vector 本身从不留下常量表达式代码。

这种完全存在于不断评估中的分配称为“临时分配”。 C++20 的规则允许这样的分配。

非瞬态分配将是“加载为 'text segment'”的数据,这是不允许的。所以你的第一印象是正确的。