假設我們有需要 FIFO 功能的情況。例如,按照它們進入的順序消費一些事件。
除此之外,我們需要不時清除整個佇列。
std::queue似乎非常適合這樣做,但不幸的是它缺少清理容器的功能。
所以在這一點上,我們有2個選擇:
std::queue
- 我們詢問了 STL 庫我們需要什么。當然,STL 庫會給我們更多:它會給我們一個
std::deque偽裝成std::queue - 我們只從我們需要的東西中取回了一部分,即流行前線和后推但沒有明確
- 我們將不得不以某種方式“模擬” clear,沒有回圈和彈出的天真方式
std::deque
- 我們詢問了 STL 庫我們需要什么
- 我們得到了我們要求的東西,但我們得到了太多:我們也有推前和彈回
總的來說,我們收到的要么太少要么太多,從來都不是我們真正想要的。
這是讓我感到驚訝的事情,而我試圖提供清晰的功能來使用std::queuewhich 是我的物件的成員 var
struct message
{
};
struct consumer
{
std::queue<message> _pending;
void clear_ver_1()
{
auto will_be_deleted_when_out_of_scope = std::move(_pending);
}
void clear_ver_2()
{
std::queue<message> will_be_deleted_when_out_of_scope;
_pending.swap(will_be_deleted_when_out_of_scope);
}
};
我已經閱讀了規格,但我不能確定是否clear_ver_1會_pending保持valid but unspecified狀態。請參閱那里的字串示例。
我很驚訝規格對這個主題如此模糊。我沒有找對地方嗎?
謝謝你們!
uj5u.com熱心網友回復:
的使用std::move
std::move 不應該這樣使用。當您不再使用它時std::move,您應該只使用將物件移動到程式中的其他位置。如您所說,然后將其置于有效但未指定的狀態:
- 有效,因為它可以完全安全地銷毀;
- 未指定,因為您不應再訪問該物件。
std::queue 對比std::deque
如果您只打算使用 FIFO 功能,我建議您使用std::queue. 它確實清楚地表明您只會將其用作 FIFO 資料結構——清晰是 首先存在std::deque 的唯一原因。std::queue
清算一個std::queue
您可以將其分配給 empty std::queue,或者像您所做的那樣,將其換成一個空的。
// ...
struct consumer
{
std::queue<message> _pending;
void clearQueue()
{
_pending = {};
}
};
根據DevSolar的評論編輯
uj5u.com熱心網友回復:
要清除佇列,您也可以簡單地撰寫
_pending = {};
注意:第一種方法可能不起作用并且不應該依賴,因為移動形式的物件處于有效但未指定的狀態。
uj5u.com熱心網友回復:
我們得到了我們要求的東西,但我們得到了太多:我們也有推前和彈回
你得到了你所要求的,adequeue是一種資料結構,它允許在任一端點進行有效的插入和洗掉。它可能不是適合您的資料結構,但選擇它是您的錯。
我們將不得不以某種方式“模擬” clear,沒有回圈和彈出的天真方式
根據記錄,彈出在性能方面非常便宜,它只是減少了一個數字。while 回圈中的彈出轉換為將整數遞減直到 0,除非您有很多數字,否則這非常快。事實上,它可能比分配記憶體要快得多,這讓我們:
清除這些集合類的 STL 方法是將它們與一個空集合交換(這是你自己想出來的),或者直接重新分配它們(蘋果的回答)。這兩者都會(可能,標準對這一點含糊不清)分配記憶體,這是一個非常昂貴的線性操作。
你有所有的事情要做,但我建議分析一下,如果它對你真的很重要,看看哪種方式更快。就我個人而言,我只是在回圈中彈出佇列,它將分配的記憶體留在原位,以便下次我需要推送更多時,因此它可以節省潛在的多次分配和重新分配(與重置佇列相比),具體取決于您擁有的資料量。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/453467.html
下一篇:我的rand()并沒有真正在C 中作業,特別是在VisualStudio2019中。我確實有“包括<time.h>和<stdlib.h>
