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:
std::priority_queue
kann nicht in einer Template-Funktion verwendet werden, die eine clear()
-Memberfunktion erwartet. 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:
clear()
nicht bereitstellen, solange niemand versucht, std::priority_queue::clear()
aufzurufen, wird der Code weiterhin kompiliert. 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): Ссылка
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.