Карты STL инициализируют примитивные типы при вставке?

У меня есть std::map:

map<wstring,int> Scores;

В нем хранятся имена игроков и баллы. Когда кто-то получает оценку, я просто делаю:

Scores[wstrPlayerName]++;

Когда на карте нет элемента с ключом wstrPlayerName он будет создавать один, но инициализирует ли он ноль или ноль до приращения или остается неопределенным?

Должен ли я проверять, существует ли элемент каждый раз перед приращением?

Я просто задавался вопросом, потому что я думал, что вещи примитивного типа всегда не определены при создании.

Если я напишу что-то вроде:

int i;
i++;

Компилятор предупреждает меня, что я не определен, и когда я запускаю программу, он обычно не равен нулю.

Ответ 1

Оператор

[] выглядит следующим образом:

Value& map<Key, Value>::operator[](const Key& key);

Если вы вызываете его с помощью ключа, который еще не отображается на карте, он по умолчанию создает новый экземпляр Значение, помещает его на карту под ключ, который вы передали, и верните ссылку на него. В этом случае у вас есть:

map<wstring,int> Scores;
Scores[wstrPlayerName]++;

Значение здесь int, а ints по умолчанию построено как 0, как если бы вы инициализировали их с помощью int(). Другие примитивные типы инициализируются аналогично (например, double(), long(), bool() и т.д.).

В конце ваш код помещает новую пару (wstrPlayerName, 0) в карту, а затем возвращает ссылку на int, которую вы затем увеличиваете. Таким образом, нет необходимости проверять, существует ли элемент, если вы хотите, чтобы что-то начиналось с 0.

Ответ 2

По умолчанию будет создан новый экземпляр value. Для целых объектов по умолчанию используется значение 0, поэтому это работает как предполагалось.

Ответ 3

Вам не следует проверять, существует ли элемент, прежде чем увеличивать его. Оператор [] делает именно то, что вам нужно, чтобы делать, как говорили другие.

Но что, если построенное по умолчанию значение не сработает для вас? В вашем случае лучший способ найти, существует ли элемент, - это попытаться его вставить. Функция-член insert для std::map возвращает a std::pair<iterator, bool>. Будет ли вставка успешной или неудачной, первый элемент пары укажет на желаемый объект (либо ваш новый, либо тот, который уже присутствовал). Затем вы можете изменить его значение по своему усмотрению.

Ответ 4

Спасибо за помощь.

Итак, std:: maps устанавливают свои значения примитивного типа в 0.

Мне просто интересно, потому что я думал, что примитивные вещи всегда undefined при создании.

Если я напишу что-то вроде:

int i;
i++;

Компилятор предупреждает меня, что я undefined, и когда я запускаю программу, он обычно не равен нулю.

Ответ 5

Проверить правила инициализации.

См. раздел 4.9.5 Инициализация STD-книги С++ Prog Lang или С++. В зависимости от того, является ли ваша переменная локальной, может возникнуть статическая, пользовательская или инициализация по умолчанию const.

В вашем случае int называется POD (обычный старый тип данных). Любая автоматическая (созданная в переменной кучи/локальная переменная) переменная POD не инициализируется по умолчанию. Следовательно, для вас "i" выше не будет иметь нулевое значение.

Всегда делайте привычку инициализировать POD, когда он определен в куче. Вы можете даже использовать int() для инициализации значения.