web-dev-qa-db-fra.com

mapper les valeurs par défaut <int, int>

std::map<int,int> mapy;
++mapy[5];

Est-il sûr de supposer que mapy[5] sera toujours 1? Je veux dire, sera mapy[5] obtient toujours la valeur par défaut de 0 avant '++', même si elle n'est pas explicitement déclarée, comme dans mon code?

63
Bill Kotsias

Dès que vous accédez à la carte avec l'opérateur [], si la clé n'existe pas, elle est ajoutée. L'initialiseur par défaut du type int est invoqué - il obtiendra donc une valeur de 0.

97
rep_movsd

Oui, il est sûr de supposer.

Le operator[] De la carte est spécifié ainsi:([map.access])

Effets: S'il n'y a pas de clé équivalente à x dans la carte, insère value_type(std::move(x), T()) dans la carte.
Renvoie: Une référence au mapped_type Correspondant à x dans *this .

T() utilise initialisation de la valeur pour tous T sauf void ([expr.type.conv]/2)et initialisation de la valeur pour une primitive se traduit par initialisation zéro  ([dcl.init]/7).

Par conséquent, l'expression est évaluée comme une référence à un objet de valeur zéro ([dcl.init]/5).

L'appel operator++ Incrémente ensuite cet objet à un et évalue à un.

(Toutes les références sont C++ 11.)

Oui, la valeur par défaut sera la valeur par défaut de ce type. Si vous voulez une autre valeur par défaut, vous pouvez créer une classe qui se comporte comme un int mais qui a un constructeur par défaut différent.

8
Rasmus Kaj

La réponse de Rep_Movsd est trop simplifiée et est susceptible de conduire à de nombreuses idées fausses extrêmement dangereuses. Les types de données primitifs en C++ n'ont pas d'initialiseurs. Louis Brandy a eu une merveilleuse conférence dans laquelle il a discuté de nombreuses erreurs C++ courantes faites sur Facebook et une mauvaise compréhension du fonctionnement de std :: map <> [] était l'une des erreurs dont il a discuté, c'est une excellente ressource bien qu'il ne le fasse pas expliquez comment std :: map <> [] fonctionne réellement.

En général, les entiers ne sont pas initialisés et ne sont pas définis comme tous les types primitifs. Cela étant dit, lorsqu'il est utilisé avec std :: map <> [], l'int a une valeur par défaut de zéro définie par un processus appelé initialisation de valeur. L'initialisation de la valeur est un processus qui fonctionne réellement avec les structures en général. Par exemple,

struct Struct {
Struct() : memberVariable() {}
       int memberVariable;
};

Initialise toujours l'int à zéro. Si les variables membres étaient d'autres types primitifs, elles auraient également des valeurs d'initialisation spécifiques. Par exemple, les types suivants sont initialisés, via l'initialisation de la valeur comme ceci:

bool = false
float = 0,0f
enum = (type d'énumération) 0
pointeur = pointeur nul
pointeur vers membre = pointeur membre nul

Soyez extrêmement prudent lorsque vous travaillez avec des données qui ne sont pas explicitement initialisées. Une dernière chose, considérez le code suivant

map<string, int> myMap;
cout << myMap["Foo"];

Ce code non seulement initialisera toujours l'entier à 0, mais il insérera également 0 dans la carte. Pour récapituler rapidement, les types de données primitifs ne sont pas définis s'ils ne sont pas initialisés, mais dans certains cas, comme avec une struct ou une initialisation de valeur de carte, les données primitives seront initialisées avec une valeur spécifique.

3
Rachel Casey