Pergunta

Apagar a chamada em std :: Definir invalidar iterator? Como fiz abaixo do 5º da última linha ..? Se sim, qual é a melhor maneira de apagar todos os elementos do conjunto

class classA
{
public:
    classA(){};
    ~classA(){};
};
struct structB
{
};

typedef std::set <classA*, structB> SETTYPE;        
typedef std::map <int, SETTYPE>MAPTYPE;

int __cdecl wmain (int argc, wchar_t* pArgs[])
{
    MAPTYPE mapObj; 
    /*
      ...
      ..   Some Operation Here
      ...
      */
    for (MAPTYPE::iterator itr1=mapObj.begin(); itr1!=mapObj.end(); itr1++) 
    {       
        SETTYPE li=(*itr1).second;
        for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();itr2++) 
        {
            classA *lt=(classA*)(*itr2);
            li.erase(itr2); 
            delete lt; // Does it invalidate Iterator ?
        }
    }
}
Foi útil?

Solução

Como você está aparentemente excluindo todos os elementos do conjunto, você pode fazer:

    for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();itr2++) 
    {
            classA *lt=(classA*)(*itr2);
            delete lt;
    }
    li.clear(); // clear the elements

Outras dicas

Do padrão 23.1.2

Os membros da inserção não devem afetar a validade dos iteradores e referências ao contêiner, e os membros apagados devem invalidar apenas iteradores e referências aos elementos apagados.

EDITAR

No seu caso, o ITR2 é invalidado após apagar tão incrementando, causa comportamento indefinido. Nesse caso, você pode seguir o conselho reko_t, em geral, você pode tentar o seguinte:

for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();) 
{
    classA *lt=(classA*)(*itr2);
    li.erase(itr2++); 
    delete lt;
}

Qual irá incrementar o iterador antes da Removendo seu valor anterior do set.
POR FALAR NISSO. ITR2 não é invalidado por delete lt;, mas por li.erase(itr2);

O delete está ok.

O problema é que você apaga - e, portanto, invalida - itr2, mas use -o para iteração de loop.

IAW após a primeira apagar, o ++itr2 tem resultados indefinidos.

O padrão que eu uso nesta situação é o seguinte:

while(itr2 != end())
{
   iterator toDelete = itr2;
   ++itr2;   // increment before erasing!
   container.erase(toDelete);
}

Alguns ITRTs de STL não padronizados retornam o próximo iterador, para que você possa fazer:

while(itr2 != end())
   itr2 = container.erase();

Isso não é portátil, no entanto.


a set<A*,B> é Estranho, porém - em um implorativo padrão, B seria o comparador.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top