std::map<int,int> mapy;
++mapy[5];
Чи можна припустити, що mapy[5]
завжди буде 1? Я маю на увазі, mapy[5]
завжди буде отримувати значення за замовчуванням 0 перед '++', навіть якщо це явно не оголошено, як у моєму коді?
std::map<int,int> mapy;
++mapy[5];
Чи можна припустити, що mapy[5]
завжди буде 1? Я маю на увазі, mapy[5]
завжди буде отримувати значення за замовчуванням 0 перед '++', навіть якщо це явно не оголошено, як у моєму коді?
Відповіді:
Як тільки ви отримуєте доступ до карти за допомогою оператора [], якщо ключ не існує, він додається. Викликається ініціалізатор за замовчуванням типу int - тому він отримає значення 0.
int
початкове значення неініціалізованого примітиву невизначене - тобто воно може бути 0 або може бути -99765521. У вас коли-небудь було неініціалізовано int
як змінну класу і чи мало одне з цих шалених значень у вашій програмі? Тим не менш, я перевірив це, і, здається, це працює. #include <stdio.h> #include <map> using namespace std; int main() { map<int,int> m ; for( int i = 0 ; i < 100 ; i++ ) m[i]++ ; for( const pair<int,int>& p : m ) printf( "m[%d] => %d\n", p.first, p.second ) ; }
Так, можна з упевненістю припустити.
Карти operator[]
вказані таким чином: ([map.access])
Ефекти: Якщо
x
на карті немає ключа, еквівалентного тому, вставляєтьсяvalue_type(std::move(x), T())
на карту.
Повертає: Посилання наmapped_type
відповіднеx
в*this
.
T()
використовує ініціалізацію значення для всіх, T
крім void
([expr.type.conv] / 2) , а ініціалізацію значення для примітиву призводить до нульової ініціалізації ([dcl.init] / 7) .
Тому вираз обчислюється як посилання на об'єкт із нульовим значенням ([dcl.init] / 5) .
Потім operator++
виклик збільшує цей об’єкт до одного і оцінює до одного.
(Усі посилання на C ++ 11.)
Так, значення за замовчуванням буде типовим для цього типу. Якщо вам потрібен інший за замовчуванням, ви можете створити клас, який поводиться як int, але має інший конструктор за замовчуванням.
Відповідь Rep_Movsd занадто спрощена і, ймовірно, призведе до численних надзвичайно небезпечних помилок. Примітивні типи даних у C ++ не мають ініціалізаторів. Луї Бренді провів чудову бесіду, в якій обговорив багато типових помилок C ++, допущених у Facebook, і нерозуміння того, як працює std :: map <> [], було однією з помилок, які він обговорював, це чудовий ресурс, хоча він цього не робить детально дізнатись, як насправді працює std :: map <> [].
Загалом, ints не ініціалізуються і невизначені, як і всі примітивні типи. Сказано, що при використанні зі std :: map <> [] int має за замовчуванням значення нуля, встановлене за допомогою процесу, який називається ініціалізацією значення. Ініціалізація значення - це процес, який насправді працює зі структурами загалом. Наприклад,
struct Struct {
Struct() : memberVariable() {}
int memberVariable;
};
Завжди ініціалізує int до нуля. Якби змінні-члени були іншими примітивними типами, вони також мали б конкретні значення ініціалізації. Наприклад, наступні типи ініціалізуються через ініціалізацію значень так:
bool = false
float = 0.0f
enum = (тип переліку ) 0
покажчик = нульовий покажчик
покажчика на member = нульовий покажчик члена
Будьте гранично обережні при роботі з даними, які не є явно ініціалізованими. Останнє, розглянемо наступний код
map<string, int> myMap;
cout << myMap["Foo"];
Цей код не тільки завжди ініціалізує ціле число до 0, але він також вставить 0 на карту. Просто для швидкого підсумовування примітивні типи даних невизначені, якщо не ініціалізовані, але в деяких випадках, наприклад, зі структурою або значенням карти, ініціалізація ініціалізує примітивні дані з певним значенням.
struct
ключового слова. Код, який ви показали, містить клас . С ++ не має конструкцій. Подальше читання: stackoverflow.com/a/36917400/560648 stackoverflow.com/a/34108140/560648