Frage

Angenommen, ich habe einen hash_map und einen Code wie

// i is an iterator
i = hash_map.erase(i)

Aber STL GCC nicht Iterator in Lösch zurück, aber eine Lücke. Nun ist ein Code wie

hash_map.erase(i++)

sicher (das heißt nicht das Iterator ungültig oder hat andere unerwartete oder unangenehme Dinge)? Bitte beachten Sie, dies ist ein hash_map.

War es hilfreich?

Lösung

Ja, das ist sicher, da der Wert von i wird auf den nächsten Wert gesetzt wurde, bevor der aktuelle Wert gelöscht wird.

Nach dem SGI Dokumentation über gehasht Container Ungültigkeits nicht für nicht auftreten -erased Elemente oder auch nur zum ändern der Größe (es gibt kein Wort darüber, ob Einfügungen verursachen ändern der Größe, so vorsichtig zu sein, ich gebe zu, als eine Möglichkeit) --- aber im letzteren Fall wird die Iteration Reihenfolge geändert. Aber dies gilt hier nicht, es sei denn, Sie aus dem Weg gehen, um den Behälter während des Traversal oder etwas zu ändern. : -)

Andere Tipps

Sie können das Löschen kapseln die gleiche Schnittstelle für alle Behälter zur Verfügung zu stellen Sie verwenden:

namespace detail {
template<typename Container, typename R>
struct SelectErase {
  // by default, assume the next iterator is returned
  template<typename Iterator>
  Iterator erase(Container& c, Iterator where) {
    return c.erase(where);
  }
};
// specialize on return type void
template<typename Container>
struct SelectErase<Container, void> {
  template<typename Iterator>
  Iterator erase(Container& c, Iterator where) {
    Iterator next (where);
    ++next;
    c.erase(where);
    return next;
  }
};

template<typename I, typename Container, typename R>
SelectErase<Container,R> select_erase(R (Container::*)(I)) {
  return SelectErase<Container,R>();
}
} // namespace detail

template<typename Container, typename Iterator>
Iterator erase(Container& container, Iterator where) {
  return detail::select_erase<Iterator>(&Container::erase).erase(container, where);
}

Dies erfordert entweder:

  1. c.erase gibt den Iterator für das nächste Element. Dies ist, wie Vektor, deque und Listen Arbeit.
  2. c.erase void zurückgibt und nicht die nächste Iterator nicht ungültig machen. Dies ist, wie Karte, Set, und (nicht-stdlib) hash_map Arbeit.

Hass auf die Parade zu regnen, aber ich glaube nicht, was Sie vorschlagen, ist sicher.

i ++ ist der Post-Inkrement-Operator, was bedeutet, i erhöht, nachdem der Anruf zu löschen. Aber Lösch entkräftet alle Iteratoren auf das Element zeigt gelöscht werden können. Also von der Zeit wird i erhöht es nicht gültig ist mehr.

Wenn Sie Glück haben es richtig funktionieren, bis eines Tages durch Zufall kann es nicht mehr.

Soweit ich weiß gibt es keine Möglichkeit, um dies aber so etwas wie:

// tmp and i are both iterators
tmp = i;
++i;
hash_map.erase(tmp);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top