事の起こり
std::list
は元のコンテナに新たな要素の挿入がされてもイテレータは無効にならない
QtのコンテナはSTLのコンテナに似せて作ってあるのだからQList
も同様だろう
そう思っていた時期が私にもありました
そしてQtがよく使っているデータ型はQStringList
QVariantList
QTestEventList
...と非常によくQList
を使用してくるのでそれに合わせて自コードをstd::list
からQList
に置き換えているときに事故は起こった
Qtのコンテナって癖あるよね
However, be aware that any non-const function call performed on the QList will render all existing iterators undefined. If you need to keep iterators over a long period of time, we recommend that you use QLinkedList rather than QList.
なんと(?)QList
では要素の挿入でイテレータが無効になるようです。
なんとQLinkedList
とかいう尤もな名前のコンテナがありました。というかQList
はリンクリストではありませんでした
(命名の重要性!)
(まあよく考えれば添え字アクセスできる時点で気付いても良かったのかも)
検証コード
Qt5.13.1 msvc2017 で検証
# include <iostream>
# include <QList>
# include <QLinkedList>
# include <QDebug>
int main()
{
std::cout << std::boolalpha;
std::list<int> a;
// QList<int> a;
// QLinkedList<int> a;
a.push_back(1);
auto b = a.begin();
auto e = a.end();
a.push_back(2);
a.push_back(3);
qDebug() << (b == a.begin()) << (e == a.end());
return 0;
}
結果
begin | end | |
---|---|---|
std::list | true | true |
QList | false | false |
QLinkedList | true | true |
はい