以下のコードを与える(名前が付けられているとしましょう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
無効化されたイテレータで操作する必要がある場所は、間違っていると予想されます。しかし、なぜコードがエラーを引き起こさないのでしょうか?