2013-06-07 3 views
11

Die STL reference scheint zwischen einer konzeptuellen Unterschied zu machen:Warum keine Front() - Methode für std :: map (und andere assoziative Container aus der STL)?

  • 'Sequence Container' (array Vektor Deque forward_list Liste) einerseits
  • 'assoziative Container' (set multiset Karte multimap unordered_set unordered_multiset unordered_map unordered_multimap) auf die andere Hand.

Auch scheint es, wie wir haben:

  • alle Container eine begin() Verfahren implementiert einen Iterator Rückkehr in den Behälter auf das erste Element zeigt.
  • Nur die Sequenzcontainer mit einer front()-Methode geben einen Verweis auf das erste Element im Container zurück.

Mein Verständnis ist, dass die front() Verfahren leicht in Bezug auf die begin() Methode definiert werden könnten, indem nur den Rückgabewert dereferencing.

So ist meine Frage: Warum ist nicht die front() Methode für alle Objekte definiert die begin() Methode definiert? (die wirklich jeder Behälter sein sollte)

(Ich denke, das aus einer semantischen Sicht ist es nicht so viel Sinn macht, das erste Element aus einer Karte zu erhalten, wie es von einem Vektor für das erste Element tut aber ich frage mich, ob es eine gültige Erklärung gab).

+2

Die beste Antwort, die ich mir vorstellen kann, ist, dass die Schnittstelle oft im Hinblick darauf spezifiziert wird, "welche Nutzung gefördert wird", sowie "was effizient implementiert werden kann". Nicht-Sequenzcontainer können immer noch iteriert werden (also müssen sie 'begin()' und 'end()' haben, aber sie sind nicht wirklich für Situationen gedacht, in denen Sie nur das erste Element von ihnen auswählen müssen 't haben 'front()', auch wenn es implementiert werden könnte – jalf

+0

Ok, das war, was ich dann erwartet habe Danke an alle für die Antworten Auch, wäre es nicht einfacher (wie in' reduzieren Menge an dupliziertem Code ') um die Methode für jeden Container ohne Unterschied zu definieren? – Josay

+0

Ich bin hier nicht gerade konstruktiv, aber: http://kera.name/articles/2010/08/it-is-not-called-the- stl-mmkay/ – wolfgang

Antwort

3

Sie müssen wirklich das Standard-Komitee fragen (comp.lang.C++. Std) aber meine Vermutung ist, dass ja, es macht einfach nicht so viel Sinn. Außerdem gibt es nicht so viel Klarheit darüber, was es bedeuten würde. Willst du die Wurzel, die Vorbestellung zuerst, nachbestellen zuerst, zuerst eingefügt ...? Bei Sequenzen ist klar: Front ist die eine Seite, die andere die andere. Karten sind Bäume.

+7

Persönlich denke ich gibt es * komplette * Klarheit was der Eintrag 'front()' bedeuten sollte wenn es existiert. Es würde bedeuten, dass derjenige, auf den sich "begin()" bezieht, dasselbe ist wie für Sequenzen. Karten haben eine Bestellung, und alles, was Sie brauchen, um ein "erstes Element" zu haben, ist eine Bestellung und nicht leer. Die Tatsache, dass es sich um Bäume handelt, ist größtenteils durch die API verborgen. Sie können eine 'std :: map' in der Reihenfolge pre-order, post-order oder insertion nicht iterieren. Sie sollten also nicht erwarten, dass' front() 'etwas mit diesen Dingen zu tun hat. –

+0

"Alles, was Sie brauchen, um ein" erstes Element "zu haben, ist eine Bestellung und nicht leer zu sein" es kommt mir vor, dass dies mathematisch gesehen ein Heuler meinerseits ist. Unendliche Mengen können eine Reihenfolge haben und haben dennoch kein Element. Was ich loslasse, ist, dass "std :: map" endlich ist. –

+0

Vielleicht liegt es daran, dass erste und letzte in 'map' nicht stabil sind. Es gibt keine 'push_front', denn das ist Kauderwelsch für einen ausgewogenen binären Baum, vielleicht aus dem gleichen Grund, warum' front' weggelassen wurde oder weil sie das Gefühl hatten, dass die beiden zusammen gehen. –

3

Vorderseite() bedeutet eine Bestellung; "der Erste in der Reihe".

Begin() bedeutet, dass wir irgendwo beginnen können, egal wo.

+8

aber es gibt eine Reihenfolge in einer Karte –

+1

sie haben eine schwache Ordnung.Theoretisch zwei oder mehr Einträge könnten Front sein.In einigen Fällen sollten alle Einträge Front sein. – Enigma

+0

'Intern werden die Elemente in einer Map immer nach dem folgenden Schlüssel sortiert ga spezifisches streng schwaches Ordnungskriterium, angezeigt durch sein internes Vergleichsobjekt (vom Typ Compare). "Aber wie Eddie sagte, sind Maps Bäume, also macht front() nicht so viel Sinn ... –

-1

STL ist entworfen, um mit Iteratoren durchlaufen werden. Also ich denke, front() macht nur Sinn für Container wie list und deque.

+3

Aber * alle * STL-Container können mit Iteratoren durchlaufen werden. Sogar 'unordered_map' – jalf

+0

Genau. Das versuche ich zu sagen. – Superman

1

ich spekulieren, dass:

  • front() und back() nicht in Reihenfolge, wenn nicht für die Tatsache bestehen würde, dass die Schnittstelle ursprünglich mit wandelbar Sequenzen konzipiert wurde. front() macht am meisten Sinn, wenn Sie darüber nachdenken, wie Sie es in Kombination mit push_front() und pop_front() verwenden würden. Für unveränderliche Sequenzen (von denen der Neuling array ist das einzige Beispiel in der Norm, wenn Sie const vector zählen), front() ist eine Kurzschrift für *begin(), die einfach nicht wert ist, sich zu freuen.

  • Da nicht in Reihenfolge geordnete Behälter keine push_front() haben, wurde es auch nicht als sinnvoll erachtet, ihnen front() zu geben. Sie können Einträge zu map hinzufügen, aber Sie können nicht angeben, wo in der Reihenfolge sie hinzuzufügen sind, da der Schlüssel für ist. Dies ist der Unterschied zwischen einer Sequenz und einer geordneten Sammlung.

  • "Hang on", Sie sagen, "vector hat front(), aber nicht push_front()". Ich vermute, dass dies ist, weil vectorback() hat - wenn Sie back() verwenden, dann ist es wieder "schön", front() zu verwenden, um es zu vergleichen.

Dies ist nur Spekulation, aber auf dem, was ich weiß, über nützliches/Befriedigung APIs entwerfen und meine Beobachtung des Container-APIs. Ich habe keine Kenntnis von Stepanows Überlegungen zu diesem Thema oder von irgendeiner Aufzeichnung seiner Diskussion im Standardkomitee.

0

Sie haben recht, es könnte recht einfach umgesetzt werden. Aber die Sache ist, dass diese Behälter für spezifische Verwendungen entworfen sind. Mit einem front() Mitglied bedeutet, dass das Ziel des Containers eine explizite Reihenfolge haben soll. Natürlich map Werte sind bestellt, aber das ist mehr eine Frage der Leistung. Und natürlich muss jede interne Struktur irgendwo beginnen (begin()), aber es gibt nur manchmal keinen Sinn, eine front() oder back() bereitzustellen.

Iteratoren sollen die Daten durchlaufen, front() Mitglieder sollen auf das erste Element einer explizit geordneten Sammlung zugreifen. Der Zugriff auf das erste Mitglied einer Karte ist nicht sinnvoll, da es assoziativ ist.

Verwandte Themen