2016-07-24 23 views
10

Betrachten Sie den folgenden Code ein:Ist der Wert von primitiven Typen in std :: map initialisiert?

map<int,int> m; 
for(int i=0;i<10000;++i) m[i]++; 
for(int i=0;i<10000;++i) printf("%d",m[i]); 

Ich dachte, die die gedruckten Werte nicht definiert werden würde, weil primitive Typen nicht Standardkonstruktor haben, aber hier habe ich 10000 1s jedes Mal, wenn ich getestet.

Warum wird es initialisiert?

+4

0 ist ein zulässiger Wert für nicht definierte Variablen. –

Antwort

12

Wenn operator[] aufgerufen wird und der Schlüssel fehlt, wird der Wert mit dem Ausdruck mapped_type() initialisiert, der der Standardkonstruktor für Klassentypen und Nullinitialisierung für ganzzahlige Typen ist.

+2

Hmm, bist du sicher, dass dies die Antwort ist? Auf [map :: operator []] (http://www.cplusplus.com/reference/map/map/operator [] /) steht: " Ein Aufruf dieser Funktion entspricht: (* ((this-> insert (make_pair (k, mapped_type()))). first)). second "was auf die Wert-Initialisierung eines Paares hinweist, ist egal –

+1

Sind Sie sicher mit cplusplus.com? – LogicStuff

+1

Chris hat einen Punkt. Der Standardkonstruktor von 'pair' wird offensichtlich nicht verwendet - das' erste' Element des Paares ist der Ganzzahlindex 'i', der hier von 0 bis 10000 läuft.Wenn der Standard-Ctor verwendet worden wäre, wäre das "erste" Mitglied Null, und da eine Karte keine doppelten Schlüssel enthalten kann, würde es nur einen einzigen Karteneintrag geben. Da wir wissen, dass 10000 Exemplare gedruckt wurden, wissen wir, dass das Standardpaar ctor nicht verwendet wurde. – MSalters

3

Siehe https://www.sgi.com/tech/stl/stl_map.h

_Tp& operator[](const key_type& __k) { 
    iterator __i = lower_bound(__k); 
    // __i->first is greater than or equivalent to __k. 
    if (__i == end() || key_comp()(__k, (*__i).first)) 
     __i = insert(__i, value_type(__k, _Tp())); 
    return (*__i).second; 
    } 

In Ihrem Beispiel _TP int ist, und int() ist 0

#include <iostream> 
using namespace std; 
int main() { 
    int x = int(); 
    cout << x << endl; 
    return 0; 
} 

Zusätzlich:

dank @MSalters, die oben über Code erzählt ist SGI anstelle von std :: map, aber ich denke es ist etwas wie ...

+0

Das ist eigentlich die STL 'map' Klasse, nicht' std :: map'. Letzteres wurde von der ersteren inspiriert, aber es gibt geringfügige Unterschiede. Und diese Frage betrifft ein winziges Detail. Aber ja, es gibt hier keine Unterschiede. – MSalters

+0

Sie haben Recht, es gibt viele STL-Versionen, SGI, STLPort, Microsoft-Version, etc. – kaitian521

+0

Wenn Microsoft jemals eine STL-abgeleitete Bibliothek hatte, war es vor 2 Jahrzehnten. (VC4 vielleicht, erinnere mich nicht an die Details). Sie haben definitiv auf die Implementierung von Dinkumware durch VC6, eine C++ 98 Standard Library-Implementierung, umgestellt. – MSalters

5

std::map::operator[] fügt einen neuen Wert ein, wenn es nicht existiert. Wenn eine Einfügung durchgeführt wird, wird der zugeordnete Wert standardmäßig durch den Konstruktor für Klassentypen oder zero-initialized initialisiert.

0

In der Standard-14 C++, Abschnitt [map.access] der Text:

T& operator[](const key_type& x);

  1. Effekte: Wenn es zu x in der Karte keine Taste entspricht, fügt value_type(x, T()) in die Karte .

So, wie auch von Joseph Garvin Antwort angegeben, ist das Ergebnis des Ausdrucks mapped_type() was eingeführt wird. Diese Art der Initialisierung wird value-initialization genannt.

Die Bedeutung der Wert-Initialisierung ist nicht ganz so einfach wie in den anderen Antworten für Klassen-Typen. Es hängt davon ab, welche Art von Konstruktoren der Klassentyp hat und ob die Klasse ein Aggregat ist, wie durch die cppreference-Verknüpfung erklärt.

Für int wie in dieser Frage bedeutet Wert-Initialisierung, dass int auf 0 gesetzt ist.