LoginSignup
1
0

More than 3 years have passed since last update.

QList のイテレータ無効化の罠

Last updated at Posted at 2019-10-03

事の起こり

std::listは元のコンテナに新たな要素の挿入がされてもイテレータは無効にならない

QtのコンテナはSTLのコンテナに似せて作ってあるのだからQListも同様だろう

そう思っていた時期が私にもありました

そしてQtがよく使っているデータ型はQStringList QVariantList QTestEventList...と非常によくQListを使用してくるのでそれに合わせて自コードをstd::listからQListに置き換えているときに事故は起こった

Qtのコンテナって癖あるよね

QList::iterator

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

はい

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0