На этом шаге мы рассмотрим представление отображения в виде ассоциативного массива.
Ассоциативные контейнеры обычно не предоставляют прямого доступа к своим элементам; все обращения к элементам производятся через итераторы. Впрочем, отображения являются исключением из этого правила. Неконстантные отображения поддерживают оператор индексирования [] для прямого доступа к элементам (таблица 1). Тем не менее в качестве "индекса" используется не целочисленная позиция элемента, а ключ, предназначенный для его идентификации. Это означает, что индекс может относиться к произвольному типу. Подобный интерфейс характерен для так называемых ассоциативных массивов.
Операция | Описание |
---|---|
m[key] | Возвращает ссылку на значение элемента с ключом key. Вставляет элемент с ключом key, если его не существует |
Ассоциативные массивы отличаются от обычных не только типом индекса. Индекс ассоциативного массива в принципе не может быть неправильным. Если элемента с заданным ключом не существует, в отображение автоматически вставляется новый элемент, значение которого инициализируется конструктором по умолчанию соответствующего типа. Чтобы эта схема работала, тип значения обязательно должен иметь конструктор по умолчанию. Базовые типы данных предоставляют конструктор по умолчанию, который инициализирует их значения нулями (смотри 34 шаг).
У ассоциативных массивов есть как свои достоинства, так и недостатки.
std::map<std::string,float> coll; //Пустая коллекция // Вставка пары "otto"/7.7 // - сначала вставляется пара "otto"/float() // - затем присваивается 7.7 coll["otto"] = 7.7;
Обратите внимание на следующую команду:
coll["otto"] =7.7;
Она работает следующим образом.
Если элемент с ключом "otto" существует, выражение возвращает значение элемента по ссылке. Если элемента с ключом "otto" не существует (как в нашем примере), в контейнер автоматически вставляется новый элемент с ключом "otto", причем значение элемента определяется конструктором по умолчанию для типа значения, и далее возвращается ссылка на значение нового элемента.
В результате в отображении появляется элемент с ключом "otto" и значением 7.7.
std::cout << coll["ottto"];
Команда вставляет в контейнер новый элемент с ключом "ottto" и выводит его значение, по умолчанию равное 0. На самом деле следовало бы вывести сообщение об ошибке с указанием на неверное написание "otto". Также следует учитывать, что этот способ вставки медленнее обычного, описанного на 177 шаге. Дело в том, что новое значение сначала инициализируется значением по умолчанию для своего типа, которое затем заменяется правильным значением.
Со следующего шага мы начнем рассматривать обработку исключений в отображениях и мультиотображениях.