C ++ доступ до елементу карти const


100

Я намагався використовувати оператор [] для доступу до елемента в const C ++ карті, але цей метод не вдався. Я також намагався використовувати "at ()", щоб зробити те саме. Це спрацювало цього разу. Однак я не зміг знайти жодної посилання на використання "at ()" для доступу до елемента в const C ++ карті. Чи "at ()" нещодавно додана функція на карті C ++? Де я можу знайти більше інформації про це? Велике спасибі!

Прикладом може бути такий:

#include <iostream>
#include <map>

using namespace std;

int main()
{
        map<int, char> A;
        A[1] = 'b';
        A[3] = 'c';

        const map<int, char> B = A;

        cout << B.at(3) << endl; // it works
        cout << B[3] << endl;  // it does not work

}

Для використання "B [3]" він повертав такі помилки під час компіляції:

t01.cpp: 14: помилка: передача 'const std :: map, std :: allocator>>' як 'цей' аргумент '_Tp & std :: map <_Key, _Tp, _Compare, _Alloc> :: operator [] ( const _Key &) [з _Key = int, _Tp = char, _Compare = std :: менше, _Alloc = std :: allocator>] 'відмовляється від кваліфікаторів

Використовуваний компілятор g ++ 4.2.1

Відповіді:


124

at()це новий метод для std::mapC ++ 11.

Замість того, щоб вставити новий сконструйований за замовчуванням елемент, як operator[]це робиться, якщо елемент із заданим ключем не існує, він видає std::out_of_rangeвиняток. (Це схоже на поведінку at()для dequeта vector.)

Через таку поведінку має сенс існувати constперевантаження at(), на відміну від operator[]якої завжди є можливість зміни карти.


Чи можливо повернути "at" значення за замовчуванням, а не викидати виняток?
user1202136

Я використовую at()у VS2013 для набору проектів для використання інструментарію VS2010. Я подумав, що це означає, що я не використовую C ++ 11 ... Але все ж він компілює ... ??
thomthom

1
Мені просто потрібно зауважити, що не має сенсу опускати оператора const [], який також може викинути виняток для неописаного елемента замість зміни карти.
Спенсер

@Spencer Було б дивно, якби const і non-const перевантаження оператора [] мали різні наслідки. Як правило, ми очікуємо, що якщо деякі об'єкти або посилання, які не є const, будуть зроблені const, програма продовжить поводитись так само, доки вона компілюється. Якщо дозволити викиди виключень лише з перенавантаженням без обмежень, це може призвести до помилок, які не потрапляють до часу виконання.
Брайан

@Brian Ви мали на увазі сказати "Дозволити лише перевантаження const кидати винятки"?
Спенсер

33

Якщо елемента не існує в a map, operator []він додасть його - що, очевидно, не може працювати у constкарті, тому C ++ не визначає constверсію оператора. Це прекрасний приклад перевірки типу компілятора, що запобігає потенційній помилці виконання.

У вашому випадку, ви повинні використовувати findзамість який буде тільки повертати (итератор на елемент) , якщо він існує, то він ніколи не буде змінювати map. Якщо елемента не існує, він повертає ітератор до карти end().

atне існує і навіть не слід компілювати. Можливо, це "розширення компілятора" (=Жук нове в C ++ 0x).


Чи забороняє стандарт C ++ впровадженню визначення додаткових нестандартних функцій членів у бібліотечних класах?
Тім Мартін

@Tim Я вважаю, що інтерфейс виправлений, так.
Конрад Рудольф

4

[] -Оператор створить новий запис на карті, якщо вказаний ключ не існує. Таким чином, це може змінити карту.

Дивіться це посилання .


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.