6

以下のコードを与える(名前が付けられているとしましょうdeque.cpp

#include <cstdio>
#include <deque>

int main()
{
  std::deque<int> d = {1, 2, 3};
  for (auto it = d.rbegin(); it != d.rend();) {
    printf("it: %d\n", *it);
    ++it;
    d.pop_back();
  }
  return 0;
}

でコンパイルするとg++ -std=c++11 -o deque deque.cpp、うまく動作します。

$ ./deque
it: 3
it: 2
it: 1

-D_GLIBCXX_DEBUGただし、 (でコンパイルするとg++ -std=c++11 -o deque_debug deque.cpp -D_GLIBCXX_DEBUG、以下のエラーが発生します。

$ ./deque_debug
it: 3
/usr/include/c++/4.8/debug/safe_iterator.h:171:error: attempt to copy-
    construct an iterator from a singular iterator.
...

2 番目のループ++itが単一のイテレータから構築されているようです。++itしかし、最初のループの後、イテレータは 2 を指しており、pop_back()それを無効にするべきではないと思います。では、なぜエラーが発生するのでしょうか?

注: コードを次のように書き直すことができることはわかっています。

  while (!d.empty()) {
    auto it = d.rbegin();
    printf("it: %d\n", *it);
    d.pop_back();
  }

そして、エラーはなくなります。

しかし、エラーコードで正確に何が起こるか知りたいです。(逆イテレータが実際に期待するノードを指しているのではなく、その次のノードを指しているということですか?)


更新: @Barry の回答で質問が解決しました。関連する追加の質問をさせてください:コード

  for (auto it = d.rbegin(); it != d.rend();) {
    printf("it: %d\n", *it);
    d.pop_back();
    ++it;   // <== moved below pop_back()
  }

++it無効化されたイテレータで操作する必要がある場所は、間違っていると予想されます。しかし、なぜコードがエラーを引き起こさないのでしょうか?

4

2 に答える 2