为什么“ std :: Deque”不是constexpr`友好?

发布于 2025-02-11 00:23:43 字数 681 浏览 2 评论 0原文

我正在学习 c ++ stl ,我注意到,尽管大多数功能都支持大多数功能。 std :: vectorstd :: array(连续存储)用constexpr标记,std ::不是这样Deque和其他非连续储藏。 因此,我花了一些时间进行一些研究,在2019年找到了一项建议,制作std :: Deque constexpr std :: Deque仍然未实现其方法的constexpr

我的困惑是std ::数组保证其元素存储在堆栈中;就像普通的C风格数组一样,应该在编译时计算出来,但是std :: vector将内存分配在堆上,因此如果在编译时进行了评估,Deque也是吗?

谢谢!

I'm learning the c++ STL and it came to my attention that while most functionalities supported by std::vector and std::array (contiguous storage) are marked with constexpr, that's not the case for std::deque and other non-contiguous storages.
So I spent some time doing some research, I found a proposal in 2019, Making std::deque constexpr, and std::deque still has not implemented constexpr for its methods.

My confusion is that std::array guarantees that its elements are stored on the stack; just like a normal C-style array, so it should be computed at compile time, but std::vector allocates memory on the heap so if it's evaluated at compile time, so is deque, right?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风吹雨成花 2025-02-18 00:23:43

根据 https://github.com/cplus.com/cplusplus/ppapers/papers/papers/issues/665通过标准委员会流程保留提案进步的日志,似乎有一些疑问是否可以在没有核心语言更改的情况下实现constexpr std :: Deque deque 。

不幸的是,它没有说明什么是特定的问题。可能某些常见的实现利用了某种语言构造,这些构造在恒定表达式中不允许使用,或者实现依赖于某些根据标准的不确定行为的结构。后者通常不是标准库的问题,因为它不受语言规则的约束,并且可以对特定编译器的行为做出假设。但是,在恒定表达式中,核心语言不确定的行为始终是一个严重的错误,因此,如果不引入魔术编译器解决方法,这种结构通常在恒定的表达上下文中可能无法使用。

如链接的GitHub问题所述,似乎还有一些图书馆设施需要添加constexpr才能使此工作。

除了这样的问题外,通常我认为没有任何理由不制作所有容器和容器适配器constexpr friendly,现在std :: Aralocator都可以使用在恒定表达式中。他们可能只想确保可以首先正确实现为constexpr。我的猜测是,出于相同的原因,只有std :: stringstd :: vector是使用C ++ 20完成的,因为这些是最简单,最重要的分配器 - 知道将constexpr应用于。 (std :: array已经constexpr更长,因为它不需要任何动态分配。)

尽管查看问题中最后一个条目的日期(如以及std :: liststd :: Pirstition_queue等的随附问题)似乎在过去两年中没有进展,也许是因为该提案没有进一步追求,但我真的不知道。


无论哪种情况,当我们说std :: vector(或其他分配器 - 感知容器)是constexpr - 友好时,这意味着与EGstd ::数组。您可以声明constexpr std :: array变量并按照使用const std :: array变量,但是您无法声明constexpr std :: vector变量(通常是完全),并像const std :: vector一样使用它。

但是,您可以做的是使用std :: vectorconstexpr函数中进行一些计算,只要在评估常数后创建变量表达开始并在结束之前被破坏。当前,如果不是std :: list不是constexpr - friendly,这是不可能的。

这样做的原因是,编译器实际上不会在编译时为容器分配内存,然后以某种方式将其传输到运行时分配(无论是静态还是动态)。取而代之的是,在编译时的动态分配与运行时分配分配,并且必须在分配末端的恒定表达式评估之前对进行

According to https://github.com/cplusplus/papers/issues/665 which keeps a log of the progression of the proposal through the standards committee process, there seem to have been some doubts whether a constexpr std::deque can be implemented without core language changes.

Unfortunately it doesn't say what the specific concern is. Probably some common implementation makes use of some language construct that specifically is not allowed in constant expressions or the implementation relies on some construct that is undefined behavior according to the standard. The latter is usually not a problem for the standard library, since it is not bound by the language rules and can make assumptions about the particular compiler's behavior. However in constant expressions core language undefined behavior is always a hard error and therefore such constructs might often not be usable in constant expression contexts without introducing magic compiler workarounds.

As mentioned in the linked github issue, there seem to also be some library facilities which need to have constexpr added to make this work as well.

Aside from such issues, generally, I don't think there is any reason to not make all containers and container adaptors constexpr-friendly now that std::allocator can be used in constant expressions. They probably just want to make sure that they can be properly implemented as constexpr first. My guess is that for the same reason only std::string and std::vector were done with C++20, since these are the simplest and most important allocator-aware containers to apply constexpr to. (std::array has been constexpr for longer since it doesn't require any dynamic allocations.)

Although, looking at the date of the last entry in the issue (as well as the accompanying issues for std::list, std::priority_queue, etc.) it seems to not have progressed in the last two years, maybe because the author of the proposal did not pursue it further, but I can't really tell.


In either case, when we say that std::vector (or other allocator-aware containers) are constexpr-friendly, this means something else than it does for e.g. std::array. You can declare a constexpr std::array variable and use it as you would use a const std::array variables, but you can't declare a constexpr std::vector variable (generally at all) and use it as you would a const std::vector.

What you can do however is use a std::vector variable in e.g. a constexpr function to do some calculations, as long as the variable is created after the evaluation of the constant expression starts and is destroyed before it ends. Currently this is not possible with e.g. a std::list which is not constexpr-friendly.

The reason for this is that the compiler will not actually allocate memory at compile-time for the container and then transfer it in some way into a runtime allocation (whether static or dynamic). Instead dynamic allocations at compile-time are separate from runtime ones and must be deallocated before the constant expression evaluation in which they were allocated ends.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文