Warum hat std :: priority_queue keine clear () -Memberfunktion?

9

Ich habe heute Hacking gemacht und herausgefunden, dass std :: priority_queue keine clear() -Memberfunktion hat. Gibt es technische Gründe dafür, warum der Normenausschuss dies ausgelassen hat?

Um es klar zu sagen, mir ist klar, dass es einfach ist, dies durch Zuweisung zu umgehen:

%Vor%

Diese Lösung ist weniger wünschenswert, weil:

  1. Es erfordert, dass Sie den Typ wiederholen - dies funktioniert unter Wartung nicht weiter. Wie @chris unten ausgeführt hat, können Sie dies vereinfachen, wenn Sie den Standardkonstruktor verwenden, aber wenn Sie einen benutzerdefinierten Vergleicher haben, ist dies möglicherweise nicht möglich.
  2. std::priority_queue kann nicht in einer Template-Funktion verwendet werden, die eine clear() -Memberfunktion erwartet.
  3. Es ist allgemein unerwünscht, dass es nicht die gemeinsame Schnittstelle der anderen Container erfüllt. Insbesondere hat alles von std::forward_list bis std::unordered_map bis std::string clear() . Die einzigen anderen Ausnahmen, die ich bemerke, sind std :: array, für das die Semantik keinen Sinn ergibt, und std::stack und std::queue , für die die Semantik fraglicher ist, wenn std::deque ohne zusätzlichen Aufwand funktioniert.

Ein Element, das wie ein Problem aussieht, aber in der Praxis nicht sein muss: Da der interne Container, der für std::priority_queue verwendet wird, templated ist und möglicherweise keine eigene clear() -Memberfunktion besitzt, führt dies zu einem interessanten Problem, insbesondere wirft es die Frage der Rückwärtskompatibilität auf. Dies ist kein Problem, weil:

  1. Bei internen Containern, die clear() nicht bereitstellen, solange niemand versucht, std::priority_queue::clear() aufzurufen, wird der Code weiterhin kompiliert.
  2. Mit SFINAE ist es möglich, die neue Schnittstelle (das clear-Member) bereitzustellen, indem Sie clear() für den internen Container aufrufen, wenn dieser verfügbar ist, und wiederholt, wenn dies nicht der Fall ist.

Es ist meiner Meinung nach ein Fehler im C ++ - Standard. Unter der Annahme, dass eine technische Diskussion keine überzeugende Begründung dafür liefert, warum diese Methode ausgelassen wurde, beabsichtige ich, die Erstellung eines Vorschlags für Normen voranzutreiben.

Bearbeiten:

Scheint, dass dies im Ausschuss behandelt wird (beachten Sie den letzten Beitrag): Ссылка

Ссылка

    
Mark 03.10.2013, 18:10
quelle

1 Antwort

4

Die Spezifikation von Containeradaptern ist bekanntlich zu pedantisch: da die "abstrakte" Spezifikation der entsprechenden Datenstruktur (aus einem Buch über abstrakte Algorithmen und Datenstrukturen) keine Operation clear enthält kanonische Prioritätswarteschlangen oder -stapel, wird sie nicht im Adapter bereitgestellt. Dies macht es in der Tat oft sehr unpraktisch, diese Adapter in der Praxis zu verwenden.

Die gute Nachricht ist jedoch, dass das innere Containerelement innerhalb des Adapters als geschütztes Mitglied des Adapters mit dem Namen c deklariert ist. Dies ist wahrscheinlich speziell für Sie getan, um in der Lage zu sein, Ihre eigene Version des Adapters einfach zu implementieren: indem Sie vom Standardadapter erben und alle Elementfunktionen hinzufügen, die Sie hinzufügen möchten, einschließlich clear .

Wie beim Vergleich der Schnittstellen dieser Adapter mit Standard-Container-Schnittstellen ... Ich denke nicht, dass es ein gültiger Vergleich ist. Diese Adapter waren niemals dazu gedacht, mit Containern in Bezug auf die Schnittstelle kompatibel zu sein. Im Gegenteil, der Zweck dieser Adapter bestand hauptsächlich darin, die öffentliche Schnittstelle der Datenstruktur einzuschränken und in die engen Grenzen dessen zu bringen, was ihre kanonische abstrakte Definition erlaubt.

Sie dürfen zum Beispiel nicht über den kanonischen Stapel iterieren. Stack ist definitionsgemäß nicht "iterierbar". Die Tatsache, dass der Stackadapter die Iterationsschnittstelle deaktiviert, ist eine gute Sache. Aber das Fehlen von clear ist sicherlich zu pedantisch, da es einen großen praktischen Wert hat, ohne wie eine große Verletzung der kanonischen Schnittstelle zu wirken.

    
AnT 03.10.2013 18:47
quelle

Tags und Links