C++20 P0784R7非瞬时分配太脆弱vs.P1004R2常量表达式std::VECTOR

2022-05-16 00:00:00 c++ stdvector c++20 constexpr

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

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

首先这似乎是不可能的,因为C++20P0784R7认为非瞬时分配太脆弱,即动态分配的内存不允许从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调用中,最终的输入源(带括号的init-list及其值)在编译时是完全已知的。是的,有一个vector,但它完全存在于常量表达式计算中。vector对象用于计算常量值,但vector本身从不留下常量表达式代码。

这种完全存在于常量求值范围内的分配称为瞬时分配。根据C++20的规则,这种分配是允许的。

非瞬时分配将是加载为‘文本段’的数据,这是不允许的。所以你的第一印象是正确的。

相关文章