Dostęp do elementów mapy const w C ++

101

Próbowałem użyć operatora [], aby uzyskać dostęp do elementu w mapie const C ++, ale ta metoda zawiodła. Próbowałem też użyć „at ()”, aby zrobić to samo. Tym razem zadziałało. Jednak nie mogłem znaleźć żadnego odniesienia do używania "at ()" w celu uzyskania dostępu do elementu w mapie const C ++. Czy „at ()” jest nowo dodaną funkcją w mapie C ++? Gdzie mogę znaleźć więcej informacji na ten temat? Dziękuję Ci bardzo!

Przykładem może być:

#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

}

Za użycie „B [3]” zwrócił następujące błędy podczas kompilacji:

t01.cpp: 14: błąd: przekazanie 'const std :: map, std :: przydzielator>>' jako 'this' argumentu '_Tp & std :: map <_Key, _Tp, _Compare, _Alloc> :: operator [] ( const _Key &) [with _Key = int, _Tp = char, _Compare = std :: less, _Alloc = std :: Alokator>] 'odrzuca kwalifikatory

Użyty kompilator to g ++ 4.2.1

lodowata
źródło

Odpowiedzi:

124

at()to nowa metoda std::mapw C ++ 11.

Zamiast wstawiać nowy domyślny skonstruowany element, jak operator[]ma to miejsce w przypadku elementu z podanym kluczem, zgłasza std::out_of_rangewyjątek. (Jest to podobne do zachowania at()for dequei vector).

Z powodu tego zachowania sensowne jest, aby było constprzeciążenie at(), w przeciwieństwie do tego, operator[]który zawsze ma potencjał do zmiany mapy.

CB Bailey
źródło
Czy jest możliwe, aby „at” zwracało wartość domyślną zamiast zgłaszać wyjątek?
user1202136
Używam at()z w VS2013 w zestawie projektu do korzystania z zestawu narzędzi VS2010. Pomyślałem, że to oznacza, że ​​nie używam C ++ 11 ... Ale mimo to się kompiluje ... ??
thomthom
1
Muszę tylko skomentować, że nie ma sensu pomijanie operatora const [], który mógłby również zgłosić wyjątek dla niezamapowanego elementu zamiast zmieniać mapę.
Spencer
@Spencer Byłoby zaskakujące, gdyby przeciążenia typu const i non-const operatora [] miały różne skutki. Zwykle oczekujemy, że jeśli niektóre obiekty niebędące stałymi lub odniesienia w programie zostaną ustawione jako stałe, program będzie zachowywał się w ten sam sposób, o ile będzie się kompilował. Zezwolenie tylko na przeciążenie inne niż stałe na zgłaszanie wyjątków może spowodować błędy, które nie zostaną wykryte do czasu wykonania.
Brian
@Brian Czy chciałeś powiedzieć „Zezwalanie tylko przeciążeniu const na rzucanie wyjątków”?
Spencer,
33

Jeśli element nie istnieje w a map, operator []doda go - co oczywiście nie może działać w constmapie, więc C ++ nie definiuje constwersji operatora. To jest ładny przykład sprawdzania typów kompilatora, który zapobiega potencjalnym błędom w czasie wykonywania.

W twoim przypadku musisz użyć findzamiast tego, który zwróci tylko (iterator do) elementu, jeśli istnieje, nigdy nie zmodyfikuje map. Jeśli element nie istnieje, zwraca iterator do mapy end().

atnie istnieje i nie powinien się nawet kompilować. Być może jest to „rozszerzenie kompilatora” (=błąd nowość w C ++ 0x).

Konrad Rudolph
źródło
Czy standard C ++ zabrania implementacji definiowania dodatkowych niestandardowych funkcji składowych w klasach bibliotecznych?
Tim Martin,
@Tim Myślę, że interfejs jest naprawiony, tak.
Konrad Rudolph
4

Operator [] utworzy nowy wpis na mapie, jeśli podany klucz nie istnieje. Może więc zmienić mapę.

Zobacz ten link .

vidstige
źródło