1

以下のコードは、C++ の priority_queue に格納されている値をダンプしようとしています:

priority_queue<Point, vector<Point>, myCmp> pq;
int i;
for (i = 0; i < 10; i++) {
    Point p(i,i);
    pq.push(p);
}
const Point& p0 = pq.top();
while(!pq.empty()) {
    cout<<p0.x<<p0.y<<endl;
    pq.pop();
}//I'm getting output like "00 11 22 33 ... 99"

コードのコメントにあるように、私の参照変数 p0 は、キューが値をポップするたびに変化し続けます。p0 は常に (0,0) オブジェクトへの参照、つまり最初のキューの先頭であるべきだと思うので、それは私には意味がありません。私は私が使用できることを知っています

Point p0 = pq.top()

フロント要素のコピーを取得して問題を回避します。それでも、誰かが参照を使用することの問題を説明できますか?

PS C++ キューについても同じことを行いましたが、この問題は観察されませんでした。

4

2 に答える 2

1

変更priority_queueした後 (ポップなど)、すべての参照が無効になります。つまり、未定義(?) の動作です

何が起こるのですか:

トップ要素への参照を取得します。の最初の要素として格納されてstd::vectorいるため、vector. 前のトップ要素を削除して新しい状態にpopping再配置する場合。vector新しい最上位要素は の最初にある必要がありますvector。したがって、vector同じ場所にある場合は、新しいトップへの参照ポイント

追加した:

参考文献:

make_pop: § 23.6.4.3/4

ボイドポップ();
4 つの効果:
pop_heap(c.begin(), c.end(), comp);
c.pop_back();

§ 25.4.6.2/2

効果: ロケーション first の値をロケーション last - 1 の値と交換し、
[first,last - 1) をヒープにします。

pop_backforが(文字列のみ)vectorとまったく同じであるという情報は見つかりませんでしたが、それは本当のようです。erase(end() - 1)

§ 23.3.6.5/3

iterator erase(const_iterator position);
iterator erase(const_iterator が最初、const_iterator が最後); 効果:消去ポイント以降の
イテレータと参照を無効にします

popしたがって、再割り当てさえ不可能なように見えるため、参照が後で新しいトップを指すことに依存することは有効であるようです。しかし、とにかくそれを使用するのは得策ではありません。


*すべてN3242への参照

于 2013-07-26T20:14:51.100 に答える