"Iterator"-Problem - wie am schönsten umgehen?



  • Hallo,
    einige kenne vielleicht folgende Situation. Gibt es konkrete Lösungsansätze, um solche Probleme zu umgehen?

    std::map<int, string> test;
    
    // kann auch von außen aufgerufen werden
    void remove(int i)
    {
    	std::map<int, string>::iterator it = test.find(i);
    
    	if (it != test.end())
    	{
    		system.notify_remove(i);
    		plugins.raise_event("notify_remove", i);
    		// mach sonst noch irgendwelche komplizierte Sachen...
    
    		test.erase(it);
    	}
    }
    
    // wird zyklisch aufgerufen
    void check_validity()
    {
    	for (std::map<int, string>::iterator it = test.begin(); it != test.end(); ++it)
    	{
    		if (system.is_invalid(it->first))
    		{
    			remove(it->first); // PROBLEM!
    		}
    	}
    }
    

    Ich habe eine solche Situation schon sehr oft gehabt und musste dann duplizierenden Code schreiben. Gibt es dafür Patterns o.Ä.?



  • Wo genau ist denn jetzt das Problem? Wenn es dir darum geht, daß du den Iterator doppelt ermitteln mußt, kannst du ja auch den Iterator als Parameter übergeben:

    void remove(int i)
    {
        std::map<int, string>::iterator it = test.find(i);
    
        if (it != test.end())
        {
            remove(it);
        }
    }
    
    void remove(std::map<int, string>::iterator pos
    {
        system.notify_remove(pos->second);
        // mach sonst noch irgendwelche komplizierte Sachen...
    
        test.erase(pos);
    }
    
    void check_validity()
    {
        for (std::map<int, string>::iterator it = test.begin(); it != test.end(); ++it)
        {
            if (system.is_invalid(it->first))
            {
                remove(it); // PROBLEM!
            }
        }
    }
    


  • Vielleicht solltest du das Problem etwas genauer erläutern, ich habe jedenfalls zwei Minuten lang versucht rauszufinden, wo da irgendetwas zyklisch aufgerufen werden soll.

    Ich schätze, es geht darum, dass remove den Iterator in check_validity() invalidiert? Das kannst du umgehen, indem du den Iterator vor dem Aufruf inkrementierst.


Anmelden zum Antworten