繁体   English   中英

为什么`std::deque`对`constexpr`不友好?

[英]Why is `std::deque` not `constexpr` friendly?

我正在学习c++ STL ,我注意到虽然std::vectorstd::array (连续存储)支持的大多数功能都标有constexpr ,但std::deque和其他非连续存储。 所以我花了一些时间做了一些研究,我在 2019 年发现了一个提案, Making std::deque constexpr ,而std::deque仍然没有为其方法实现constexpr

我的困惑是std::array保证其元素存储在堆栈中; 就像一个普通的 C 风格的数组,所以它应该在编译时计算,但是std::vector在堆上分配内存,所以如果它是在编译时计算的,那么双端队列也是如此,对吗?

谢谢!

根据https://github.com/cplusplus/papers/issues/665通过标准委员会流程记录提案的进展情况,似乎有人怀疑是否可以实施constexpr std::deque无需更改核心语言。

不幸的是,它没有说明具体问题是什么。 可能一些常见的实现使用了一些在常量表达式中明确不允许的语言构造,或者实现依赖于一些根据标准未定义的行为的构造。 后者对于标准库来说通常不是问题,因为它不受语言规则的约束并且可以对特定编译器的行为做出假设。 然而,在常量表达式中,核心语言未定义的行为总是一个硬错误,因此如果不引入神奇的编译器变通方法,这样的构造可能通常无法在常量表达式上下文中使用。

如链接的 github 问题中所述,似乎还有一些库设施需要添加constexpr才能使其正常工作。

除了这些问题,一般来说,我认为没有任何理由不让所有容器和容器适配器对constexpr友好,因为std::allocator可以在常量表达式中使用。 他们可能只是想确保它们可以首先正确地实现为constexpr 我的猜测是,出于同样的原因,只有std::stringstd::vector是用 C++20 完成的,因为它们是应用constexpr的最简单和最重要的分配器感知容器。 std::array已经constexpr的时间更长了,因为它不需要任何动态分配。)

虽然,查看问题中最后一个条目的日期(以及std::liststd::priority_queue等的随附问题),它似乎在过去两年中没有进展,可能是因为作者的建议没有进一步追究,但我真的不能说。


在任何一种情况下,当我们说std::vector (或其他分配器感知容器)是constexpr友好的时,这意味着它与例如std::array不同。 您可以声明一个constexpr std::array变量并像使用const std::array变量一样使用它,但是您不能声明一个constexpr std::vector变量(通常根本没有)并像使用它一样使用它const std::vector

但是,您可以做的是在例如constexpr函数中使用std::vector变量来进行一些计算,只要该变量是在常量表达式的评估开始之后创建并在它结束之前被销毁的。 目前这是不可能的,例如std::list不是constexpr友好的。

原因是编译器实际上不会在编译时为容器分配内存,然后以某种方式将其转移到运行时分配中(无论是静态的还是动态的)。 相反,编译时的动态分配与运行时的分配是分开的,并且必须在分配它们的常量表达式评估结束之前解除分配。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM