[英]Why is `std::deque` not `constexpr` friendly?
我正在學習c++ STL ,我注意到雖然std::vector
和std::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::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
。
但是,您可以做的是在例如constexpr
函數中使用std::vector
變量來進行一些計算,只要該變量是在常量表達式的評估開始之后創建並在它結束之前被銷毀的。 目前這是不可能的,例如std::list
不是constexpr
友好的。
原因是編譯器實際上不會在編譯時為容器分配內存,然后以某種方式將其轉移到運行時分配中(無論是靜態的還是動態的)。 相反,編譯時的動態分配與運行時的分配是分開的,並且必須在分配它們的常量表達式評估結束之前解除分配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.