map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];
Я спантеличений, бо не знаю, вважається це невизначеною поведінкою чи ні, як дізнатися, коли я запитую ключ, якого не існує, чи просто використовувати замість цього find?
Відповіді:
У map::operator[]
пошуках структури даних для значення , відповідні заданого ключ, і повертає посилання на нього.
Якщо він не може його знайти, він прозоро створює для нього сконструйований елемент за замовчуванням. (Якщо ви не хочете такої поведінки, ви можете використовувати map::at
функцію замість цього.)
Ви можете отримати повний перелік методів std :: map тут:
http://en.cppreference.com/w/cpp/container/map
Ось документація map::operator[]
з поточного стандарту C ++ ...
T& operator[](const key_type& x);
Ефекти: Якщо на карті немає ключа, еквівалентного x, вставляє value_type (x, T ()) на карту.
Потрібно: type_type повинен бути CopyConstructible, а mapped_type - DefaultConstructible.
Повертає: Посилання на mapped_type, що відповідає x у * this.
Складність: логарифмічна.
T& operator[](key_type&& x);
Ефекти: Якщо на карті немає ключа, еквівалентного x, вставляє value_type (std :: move (x), T ()) на карту.
Потрібно: mapped_type має бути DefaultConstructible.
Повертає: Посилання на mapped_type, що відповідає x у * this.
Складність: логарифмічна.
ISO/IEC 14882:2011(E)
?
Якщо ви спробуєте отримати доступ до key value
використовуваного оператора індексу []
, може статися 2 речі:
key
. Тож він поверне відповідне key value
.key
. У цьому випадку він автоматично додасть а key
на карту за допомогою null value
."pootoo"
ключ не існує на вашій карті. Тому він автоматично додасть це за key
допомогою value = ""
(порожній рядок). І ваша програма надрукує порожній рядок.
Тут розмір карти збільшиться на 1
.
Для пошуку ключа можна скористатися map_name.find()
, який повернеться, map_name.end()
якщо ключа не існує. І ніяких додаткових key
додавати не буде.
Ви можете використовувати []
оператор, коли ви хочете встановити значення ключа.
Це не невизначена поведінка. Якщо operator []
не знаходить значення для наданого ключа, він вставляє його в цю позицію.
Для оператора [], якщо ви намагаєтеся отримати доступ до значення для ключа, який не існує, новий об’єкт значення, який був побудований за замовчуванням, буде поміщений на карту і повернене посилання.
operator[]
Для map
повернення неконстантная посилання і ви можете призначити з допомогою цього в тому , як ви показали на другій лінії. Доступ таким чином створить елемент value
типу типу, виконаний за замовчуванням .
Якщо ви хочете знайти елемент пошуку, це кращий спосіб
iterator find ( const key_type& x )
(або альтернатива const), яка поверне ітератор, рівний, <map>.end()
якщо він не знаходить ключ, або якщо ви просто хочете знати, чи є він у колекції, яку ви можете використовувати
size_type count ( const key_type& x ) const
який завжди повертає або 1, або 0 для карти, оскільки ключі унікальні.
Якщо оператор [] не знаходить значення для наданого ключа, він вставляє його в цю позицію.
Але ви повинні зауважити, що якщо ви відвідаєте not exist key
та викличете його функцію-члена, як-от mapKV [not_exist_key] .member_fun (). Програма може вийти з ладу.
Наведу приклад, тестовий клас, як показано нижче:
struct MapValue{
int val;
MapValue(int i=0){
cout<<"ctor: "<<i<<endl; val = i;
}
~MapValue(){
cout<<"dtor: "<<val<<endl;
}
friend ostream& operator<<(std::ostream& out, const MapValue& mv){
cout<<"MapValue: "<<mv.val<<endl;
}
string toString(){
cout<<"MapValue: "<<val<<endl;
}
};
Тестовий код:
cout<<"-------create map<int, MapValue>-------"<<endl;
map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};
cout<<"-----cout key[2]-----"<<endl;
cout<<idName[2]<<endl;
cout<<"-----cout key[5]-----"<<endl;
cout<<idName[5]<<endl;
cout<<"------- runs here means, does't crash-------"<<endl;
Результат, як показано нижче:
-------create map<int, MapValue>-------
ctor: 1
ctor: 2
dtor: 2
dtor: 1
dtor: 2
dtor: 1
-----cout key[2]-----
MapValue: 2
-----cout key[5]-----
ctor: 0
MapValue: 0
-------runs here means, does't crash-------
dtor: 0
dtor: 2
dtor: 1
Ми бачимо, що: idName[5]
викликати конструкцію map {5, MapValue(0)}
для вставки в idName.
Але якщо ви викликаєте функцію-член до idName[5]
, тоді програма аварійно завершує роботу:
cout<<"-------create map<int, MapValue>-------"<<endl;
map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};
idName[5].toString(); // get crash here.
cout<<"------- runs here means, doesn't crash-------"<<endl;
Будь ласка, подивіться виняток out_of_range: http://www.cplusplus.com/reference/stdexcept/out_of_range/
це те, що викине map :: at і map :: operator [], якщо ключ не існує. Ви можете зрозуміти це так само, як векторний приклад у посиланні.
Ви також можете використовувати: http://www.cplusplus.com/reference/map/map/find/
І порівняйте з map :: end