簡體   English   中英

C ++ priority_queue pop()和top()差異

[英]C++ priority_queue pop() and top() discrepancy

我很難理解為什么priority_queue pop()調用沒有刪除top()元素。 優先級隊列具有自定義比較結構,因此,較低的數字具有較高的優先級(因此應使用top()進行檢索)。

調試文本(如下)顯示,即使在pop()之后,top()元素也保持不變。

即使我們假設比較結構有某種錯誤,top()應該在pop()之后更改,對嗎? 我還能看些什么以了解為什么會這樣。 目前,priority_queue代碼本身對我來說有點難以理解。

請注意,此行為不一致。 在其他情況下,top()在pop()之后更改。

有任何想法嗎? 謝謝!

調試文本(在push()之前顯示的top()中進行了編輯:

size BEFORE push(): 1 TOP: [1488994840.745965281:0106996627] APPENDING: [1488994840.746157190:0106996627]
size  AFTER push(): 2 TOP: [1488994840.745965281:0106996627]
size BEFORE  pop(): 2 TOP: [1488994840.745965281:0106996627]
size  AFTER  pop(): 1 TOP: [1488994840.745965281:0106996627] // <- same top()!!

我將()推送到priority_queue的位置:

void Replica::appendPrepareOK(const PrepareOK &prepareOK) {
    PendingPrepare tmpPrepareOK = prepareOK;

    lock_guard<mutex> lck (this->lockPendingPrepare);

    this->logprint(3, "size BEFORE push(): " + to_string(this->pendingPrepare.size()) + " APPENDING: " + to_string(tmpPrepareOK));

    this->pendingPrepare.push(tmpPrepareOK);

    this->logprint(3, "size  AFTER push(): " + to_string(this->pendingPrepare.size()) + " TOP: " + to_string(this->pendingPrepare.top()));
}

我在priority_queue中彈出()的地方:

void Replica::sendPendingCmds() {
    ClockCommand *prepareCmd = NULL;
    PrepareOK *prepareOKCmd = NULL;
    Broadcast *broadcastCmd = NULL;

    {
        lock_guard<mutex> lck(this->lockPendingPrepare);

        if (! this->pendingPrepare.empty()) {
            this->logprint(3, "size BEFORE pop(): " + to_string(this->pendingPrepare.size()) + " TOP: " + to_string(this->pendingPrepare.top()));

            PendingPrepare firstCommand = this->pendingPrepare.top();
            this->pendingPrepare.pop();

            if (! this->pendingPrepare.empty()) {
                this->logprint(3, "size  AFTER pop(): " + to_string(this->pendingPrepare.size()) + " TOP: " + to_string(this->pendingPrepare.top()));
            }
            else {
                this->logprint(3, "size  AFTER pop(): " + to_string(this->pendingPrepare.size()));
            }

priority_queue的定義:

typedef priority_queue<PendingPrepare, deque<PendingPrepare>, PendCompare> pendQueue;

自定義PendCompare比較類:

class PendCompare {
public:
    bool operator() (const PendingPrepare &a, const PendingPrepare &b) const {
        if (a.prepareOK != NULL) {
            if (b.prepareOK != NULL) { return a.prepareOK->tsOK > b.prepareOK->tsOK; }
            else if (b.prepare != NULL) { return a.prepareOK->tsOK > b.prepare->ts; }
        }
        else if (a.prepare != NULL) {
            if (b.prepareOK != NULL) { return a.prepare->ts > b.prepareOK->tsOK; }
            else if (b.prepare != NULL) { return a.prepare->ts > b.prepare->ts; }
        }

        return false;
    }
};

PendingPrepare結構的相關部分:

struct PendingPrepare {
    ClockCommand* prepare = NULL;
    PrepareOK* prepareOK = NULL;

    void operator=(const PrepareOK &b) {
        this->prepareOK = new PrepareOK(b);
    }
};

感謝大家的協助。 實際查看PendingPrepare內容可以解決此問題。 我做出了可怕的假設,即一次只有一個指針被實例化,而有時會同時實例化兩個指針,這使PendCompare比較類感到困惑。

更好的復制構造函數刪除了另一個指針並使其為NULL,以避免多個實例化,從而解決了該問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM