Ric*_*yen 7 c++ vector deque constexpr
我正在学习c++ STL,我注意到虽然std::vectorand std::array(连续存储)支持的大多数功能都标有,但和 其他非连续存储的constexpr情况并非如此。std::deque所以我花了一些时间做了一些研究,我在 2019 年发现了一个提案,Making std::dequeconstexpr,但它的方法std::deque仍然没有实现。constexpr
我的困惑是std::array保证它的元素存储在堆栈上;就像普通的 C 风格数组一样,所以它应该在编译时计算,但std::vector在堆上分配内存,所以如果它在编译时评估,那么 deque 也是如此,对吗?
谢谢!
根据https://github.com/cplusplus/papers/issues/665(它通过标准委员会流程记录了提案的进展情况),似乎有人怀疑是否constexpr std::deque可以在不更改核心语言的情况下实现 a 。
不幸的是,它没有说明具体的问题是什么。可能某些常见的实现使用了常量表达式中明确不允许的某些语言构造,或者该实现依赖于根据标准未定义行为的某些构造。后者对于标准库来说通常不是问题,因为它不受语言规则的约束,并且可以对特定编译器的行为做出假设。然而,在常量表达式中,核心语言未定义的行为始终是一个硬错误,因此,如果不引入神奇的编译器解决方法,此类构造通常可能无法在常量表达式上下文中使用。
正如链接的 github 问题中提到的,似乎还需要constexpr添加一些库设施才能使这项工作正常进行。
除了这些问题之外,一般来说,我认为没有任何理由不让所有可以在常量表达式中使用的容器和容器适配器constexpr变得友好。std::allocator他们可能只是想确保它们能够constexpr首先得到正确实施。我的猜测是,出于同样的原因,std::string并且std::vector是使用 C++20 完成的,因为这些是要应用的最简单且最重要的分配器感知容器constexpr。(std::array已经存在constexpr很长时间了,因为它不需要任何动态分配。)
虽然,从该问题最后一个条目的日期(以及std::list、std::priority_queue等的随附问题)来看,过去两年似乎没有取得进展,也许是因为该提案的作者没有进一步追求它,但我实在说不出来。
在任何一种情况下,当我们说std::vector(或其他分配器感知容器)是constexpr友好的时,这意味着与例如不同的东西std::array。您可以声明一个constexpr std::array变量并像使用const std::array变量一样使用它,但是您不能声明一个constexpr std::vector变量(通常根本不能)并像使用const std::vector.
然而,您可以做的是std::vector在例如constexpr函数中使用变量来执行一些计算,只要该变量在常量表达式的求值开始后创建并在结束前销毁即可。std::list目前,对于例如不友好的a 来说,这是不可能的constexpr。
原因是编译器实际上不会在编译时为容器分配内存,然后以某种方式将其转移到运行时分配(无论是静态还是动态)。相反,编译时的动态分配与运行时的动态分配是分开的,并且必须在分配它们的常量表达式求值结束之前释放。