1

スタックの最上位要素への参照に混乱しています。

#include <iostream>
#include <stack>
using namespace std;

int main()
{
    stack<int> s;
    s.push(1);

    int        x = s.top();
    int&       y = s.top();
    const int& z = s.top();

    cout << x << '\t' << y << '\t' << z << endl;

    s.pop();
    s.push(2);

    cout << x << '\t' << y << '\t' << z << endl;
}
/* Output:
1       1       1
1       2       2
 */

一番上の要素への参照は変更すべきではないと思っていましたが、新しい要素がスタックにプッシュされた後、参照が参照する値が変更されます。

intタイプがスタック用ではない場合、タイプがMyClass(非常に大きなデータ)であると言うと、古い最上位要素を安全に参照する方法があるので、これは私には奇妙です。(コストのかかるコピー操作をしたくないため)。

この動作は実装に依存する可能性があると思います。

4

2 に答える 2

3

C++11 標準に記載されているとおり (23.6.5.2 -stack定義)

reference top() { return c.back(); }
const_reference top() const { return c.back(); }
...
void push(const value_type& x) { c.push_back(x); }
void push(value_type&& x) { c.push_back(std::move(x)); }
...
void pop() { c.pop_back(); }

デフォルトの基になるコンテナを使用している場合std::dequeイテレータ/参照の無効化ルールは次のように述べています(この回答から引用):

deque: 最後の要素を消去すると、反復子と、消去された要素への参照と末尾反復子のみが無効になります。最初の要素を消去すると、反復子と消去された要素への参照のみが無効になります。他の要素を消去すると、すべての反復子と参照が無効になります (過去の反復子を含む) [23.3.3.4/4]

を使用することで、上記のように、以前に によって返された参照を無効にstd::stack::popする呼び出しを行う必要があります(これは後で を呼び出します)。したがって、この動作は定義されておらず、移植性がなく、間違っているため、決してこの動作に依存しないでください。std::deque::pop_back()std::stack::topstd::deque::back()

したがって、スタックのトップの元の値が必要な場合の解決策は、トップ要素をコピーし、それへの参照を持たないようにすることです。つまり、要素をスタックからポップした後、元の値を正しく保持したい場合です。

于 2013-08-12T05:58:40.953 に答える
2

pop() の後、参照は無効です。std::stack の実装の詳細により、出力には新しくプッシュされた値が表示されます。これに依存しないでください。これもゴミになる可能性があります。

于 2013-08-12T05:41:53.530 に答える