Tengo dos std::map<>objetos ay me bgustaría mover ( extract+ insert) algunos elementos (nodos) de un mapa a otro según algún predicado p.
for (auto i = a.begin(); i != a.end(); ++i)
if (p(*i))
b.insert(a.extract(i))
Este código se divide en clang. Supongo que el problema es el incremento de idespués de que su nodo se haya extraído de a.
¿Es la forma correcta / única de solucionar esto usando un post-incremento ?, por ejemplo:
for (auto i = a.begin(); i != a.end();)
if (p(*i))
b.insert(a.extract(i++))
else
++i;
EDITAR : eliminé la parte sobre "¿por qué esto funciona en gcc?", Porque no puedo reproducir esto en mi configuración actual. Estoy convencido de que solía hacerlo en algún momento, pero con gcc 9.2.1 obtengo un punto muerto (en lugar de un segfault). De cualquier manera, incrementar después extract()no funciona.

std::setystd::mapson muy similares, y por lo que puedo decirextracttiene las mismas implicaciones de invalidación queerase.Respuestas:
En efecto. La extracción invalida los iteradores del elemento extraído, y
ies ese iterador. El comportamiento de incrementar o indirectamente a través de un iterador no válido no está definido.Porque el comportamiento del programa no está definido.
Es una forma correcta de solucionar esto. No es una manera particularmente mala. Si prefiere no repetir el incremento, un enfoque es usar una variable:
fuente
currentse quedaría en un estado de mudanza . Cualquiera que sea ese estado no importará ya que ya no se usa después de eso.currentutilizando laif (auto current = ++i; p(*current))sintaxis de c ++ 17s .