Question: Is it a don't do it that delete a element of map in a loop?

//std::set<Battle::BattleBuf *> m_bufs; for (auto& pBuf : m_bufs) { pBuf->doEffect(pDef, param); // It can a deep call stack, and may call m_bufs.erase if(pBuf == nullptr || m_bufs.empty()) { ERROR_LOG("condbuffs is empty"); return; } }

Iterator may invalidate during the ranged for loop. There's a naive solution, doEffect() can return the iterator returned by erase. But since it could be a deep call stack, it's almost impossible. How to solve this problem, or it's just a design red flag. It's hard to track whether it may cause invalidation when writing code.

Background: I maintain a skill module in game, a buff may have dismiss buffs effect

Searcher's user avatar

3

The code does not utilize iterators. You should use them and a next iterator.

for (auto it = m_bufs.begin(); it != m_bufs.end(); ;) { auto *cur = *it++; cur->doEffect(pDef, param); }

This specific code in the Q can be made a bit shorter

for (auto it = m_bufs.begin(); it != m_bufs.end(); ;) { (it++)->doEffect(pDef, param); }

3CEZVQ's user avatar

3 Comments

OK, I understand. References and iterators to the erased elements are invalidated. Other references and iterators are not affected.

2026-02-04T06:50:15.207Z+00:00

What if it may erase several elements, so it should take another design?

2026-02-04T06:53:25.453Z+00:00

You can iterate through a copy of the map. Or, don't erase but reset deleted elements to nullptr and clean the map after the loop.

2026-02-04T06:58:25.233Z+00:00

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.