Ο καλύτερος τρόπος για να in situ διαγράψετε ένα στοιχείο

ψήφοι
2

Έχω μια σειρά από αντικείμενα που έχω επαναλάβει μέσω, όμως αυτό μπορεί να αποφασίσει κατά την επανάληψη ότι ένα (ή περισσότερα) από αυτά τα αντικείμενα πρέπει τώρα να διαγραφεί.

κωδικό μου πηγαίνει ως εξής:

if( ! m_Container.empty() )
    {
        for(  typedefedcontainer::iterator it = m_Container.begin();
              it != m_Container.end(); 
              ++it  )
        {
            if( ! ( SomeFunction( (*it), test, TEST!, false ))  )
            {
            // If function returns false, delete object.
                m_Container.erase( it );
                AsyncResponseStore::iterator it = m_asyncResponses.begin();
            }

        }


    }

Αλλά φυσικά, όταν διαγράψετε ένα αντικείμενο παίρνω ένα σφάλμα: «Χάρτης / σύνολο iterator δεν incrementable». Μπορεί κάποιος να προτείνει έναν καλύτερο τρόπο για να γίνει αυτό;

Δείτε: Τι θα συμβεί αν σας καλέσει διαγράψει () σε ένα στοιχείο χάρτη, ενώ επανάληψη από το να αρχίσει να τελειώσει;

Δημοσιεύθηκε 09/12/2008 στις 17:09
πηγή χρήστη
Σε άλλες γλώσσες...                            


3 απαντήσεις

ψήφοι
6

Αν το δοχείο υποστηρίζει (που υποψιάζομαι το δικό σας δεν κάνει, αλλά ο τίτλος ερώτημα είναι γενική και έτσι αυτό μπορεί να είναι χρήσιμο για τους άλλους, αν δεν σας):

struct SomePredicate {
    bool operator()(typedefedcontainer::value_type thing) {
        return ! SomeFunction(thing, "test", "TEST", false);
    }
};

typedefedcontainer::iterator it;
it = std::remove_if(m_Container.begin(), m_Container.end(), SomePredicate());
m_Container.erase(it, m_Container.end());

m_Container πρέπει να έχει μια μέθοδο φάσμα διαγραφής, η οποία περιλαμβάνει οποιαδήποτε αλληλουχία ή Συνειρμική Container. Δεν χρειάζεται να έχει ένα μεταβλητό iterator, όμως, και εγώ απλά παρατήρησα ότι αρχικά παρερμηνεύει το μήνυμα λάθους: λέει «χάρτη / που iterator δεν incrementable». Έτσι υποθέτω δοχείο σας είναι ένας χάρτης ή ένα σύνολο.

Σημειώστε ότι τα τρία τελευταία θα μπορούσε να είναι ένα πραγματικά υπέροχο με ένα σκάφος της γραμμής, αλλά αυτό το περιθώριο είναι πολύ στενό για να το περιέχει.

Επίσης, ότι SomePredicate θα μπορούσε να έχει κατασκευαστή με τις παραμέτρους για να αποθηκεύσει τις πρόσθετες παραμέτρους για να someFunction, δεδομένου ότι στην πραγματική ζωή υποθέτω ότι είναι μη σταθερή.

Θα μπορούσε πραγματικά να απαλλαγούμε από SomePredicate εξ ολοκλήρου, αν χρησιμοποιείτε ώθηση: συνδέονται με την κατασκευή του functor. ένα σκάφος της γραμμής σας τότε θα είναι πραγματικά τεράστια.

[Επεξεργασία: Rob Walker ορθώς επισημαίνει στην απάντησή του, μια υπόθεση που κάνω εδώ και ότι το ζήτημα δεν αναφέρει, το οποίο είναι ότι όλοι διαγραφή μπορεί να αναβληθεί μέχρι μετά το επαναλάβει-and-test γίνεται. Αν someFunction πρόσβαση m_Container από ένα κρυφό διαδρομή (π.χ. παγκόσμια, είτε επειδή someFunction είναι στην πραγματικότητα μια συνάρτηση-μέλος αυτού), και τα αποτελέσματά της εξαρτώνται από το περιεχόμενο του δοχείου, τότε κωδικό μου μπορεί να μην είναι ισοδύναμο με τον κωδικό του ερωτώντος. Αλλά νομίζω κωδικό μου είναι η «εκτός και αν υπάρχει ένας λόγος για να μην» προεπιλογή.]

Απαντήθηκε 09/12/2008 στις 17:39
πηγή χρήστη

ψήφοι
6

Εξαρτάται από το δοχείο. Το δοχείο λίστα υποστηρίζει τη διαγραφή κατά την απαρίθμηση επιστρέφοντας ένα νέο iterator από τη μέθοδο διαγραφής που αντιπροσωπεύει το επόμενο στοιχείο της λίστας. χάρτης δεν υποστηρίζει αυτό.

Μια απλή μέθοδος για χάρτη είναι να συγκεντρώσει τα στοιχεία που θέλετε να διαγράψετε σε μια ξεχωριστή λίστα, και στη συνέχεια να επαναλάβει πάνω από αυτόν τον κατάλογο, όταν έχετε ολοκληρώσει την επεξεργασία του χάρτη για να διαγράψετε τα στοιχεία από τον χάρτη. Αυτό προϋποθέτει ότι μπορείτε να αναβάλει τη διαγραφή έως ότου ολοκληρωθεί η επανάληψη. Αν όχι, τότε δεν έχετε καμία επιλογή αλλά για την επανεκκίνηση της επανάληψης για κάθε διαγραφή.

Απαντήθηκε 09/12/2008 στις 17:18
πηγή χρήστη

ψήφοι
0

Καθορίζονται από τα παρακάτω:

for(  typedefedcontainer::iterator it = m_Container.begin();
      it != m_Container.end(); 
        )
{
    if( ! ( SomeFunction( (*it), "test", "TEST!", false ))  )
    {
    // If function returns false, delete object.
        m_Container.erase( it++ );
    }
    else
    { 
        ++i;
    } 

}

Όταν ένα στοιχείο διαγράφεται, όλοι οι δείκτες να γίνει ακυρωθεί. Ως εκ τούτου από τη χρήση ++ έχουμε γύρω από αυτό. Χάρη σ 'αυτούς που δημοσιεύτηκε προτάσεις.

Απαντήθηκε 09/12/2008 στις 17:30
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more