Is it possible to have correct std::map with an std::list::iterator inside the class?

73 Views Asked by At

In the private section of the class, I have this:

private:
    std::list<QTextCursor> m_cursorList;
    std::map<int, std::list<QTextCursor>::iterator> m_cursorMap;

And I have a function it does some magic:

void addCursor(QTextCursor cursor)
{
    if (cursor.isNull())
        return;
    
    QTextCursor c1 = cursor;

    const int pos = c1.position();
    qDebug() << " ";
    qDebug() << "pos" << pos;
    if (m_cursorMap.find(pos) != m_cursorMap.end()) {
        qDebug() << "erasing" << &(*m_cursorMap[pos]);
        qDebug() << "size before" << m_cursorList.size();
        const auto c2 = *m_cursorMap[pos];
        for (auto it = m_cursorList.begin(); it != m_cursorList.end(); ++it)
            qDebug() << "before erase" << &(*it);
        m_cursorList.erase(m_cursorMap[pos]);
        for (auto it = m_cursorList.begin(); it != m_cursorList.end(); ++it)
            qDebug() << "after erase" << &(*it);
        qDebug() << "size after" << m_cursorList.size();
        m_cursorMap.erase(pos);
    }

    const auto itc = m_cursorList.insert(m_cursorList.end(), c1);
    const auto itc2 = --m_cursorList.end();
    m_cursorMap[pos] = itc;
    qDebug() << "inserting" << &(*itc) << &(*itc2) << m_cursorList.size();
    for (auto it = m_cursorList.begin(); it != m_cursorList.end(); ++it)
        qDebug() << "after inserting" << &(*it);
}

log:

pos 0
inserting 0x55d774127fc0 0x55d774127fc0 1
after inserting 0x55d774127fc0
 
pos 0
erasing 0x55d774127fc0
size before 1
before erase 0x55d77408b4e0
after erase 0x55d77408b4e0
size after 0
inserting 0x55d774127fc0 0x55d774127fc0 1
after inserting 0x55d77408b4e0
after inserting 0x55d774127fc0
 
pos 0
erasing 0x55d774127fc0
size before 2
before erase 0x55d7740fd440
before erase 0x55d7740fd420
after erase 0x55d7740fd440
after erase 0x55d7740fd420
size after 1
inserting 0x55d774127fc0 0x55d774127fc0 2
after inserting 0x55d7740fd440
after inserting 0x55d7740fd420
after inserting 0x55d774127fc0
 
pos 317914
inserting 0x55d774bd0fa0 0x55d774bd0fa0 4
after inserting 0x55d774ba32e0
after inserting 0x55d774ba38c0
after inserting 0x55d774ba38e0
after inserting 0x55d774bd0fa0
 
pos 0
erasing 0x55d774127fc0
size before 4
before erase 0x55d77408b4e0
before erase 0x55d7740fcf40
before erase 0x55d7740fd520
before erase 0x55d774b9d4f0

And the problem with "m_cursorList.erase(m_cursorMap[pos]);". So when I try to delete the iterator, the size of the list stays the same. I've checked iterator addresses. And between several calls of the function iterators of m_cursorList become changed. So the iterator is valid and dereferenceable because the line "auto c2 = *m_cursorMap[pos];" works. But I can see that iterators are different between the two calls. Could you tell me if it is normal behaviour or not? And are there any other ways to do so without iterators? I know that I can use set, list, and unordered_map. But I am still more curious about iterator stuff.

P.S. I double-checked the code and didn't do any other modifications with the list or map, which can cause iterator invalidation. This approach works for me when the map and the list are inside one function, but when I move it to the class level it causes some trouble.

0

There are 0 best solutions below