Poniższy kod mówi, że przekazanie mapy as const
do operator[]
metody powoduje odrzucenie kwalifikatorów:
#include <iostream>
#include <map>
#include <string>
using namespace std;
class MapWrapper {
public:
const int &get_value(const int &key) const {
return _map[key];
}
private:
map<int, int> _map;
};
int main() {
MapWrapper mw;
cout << mw.get_value(42) << endl;
return 0;
}
Czy to z powodu możliwej alokacji, która występuje na mapie dostępu? Czy żadne funkcje z dostępem do mapy nie mogą być deklarowane jako stałe?
MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers
Odpowiedzi:
std::map
„soperator []
nie jest zadeklarowana jakoconst
, i nie może być ze względu na jego zachowanie:W rezultacie Twoja funkcja nie może zostać zadeklarowana
const
i użyj funkcji mapyoperator[]
.std::map
„sfind()
funkcja pozwala zajrzeć do klucza bez modyfikowania map.find()
zwracaiterator
lubconst_iterator
dostd::pair
zawierającego zarówno klucz (.first
), jak i wartość (.second
).W C ++ 11 można również użyć
at()
forstd::map
. Jeśli element nie istnieje, funkcja zgłaszastd::out_of_range
wyjątek, w przeciwieństwie dooperator []
.źródło
operator[]
(np.foo[bar] = baz
) I rvalueoperator[]
(np.x = foo[bar]
) - ta ostatnia z pewnością mogłaby być const.Ponieważ
operator[]
nie ma przeciążenia z kwalifikacją stałą, nie można go bezpiecznie używać w funkcji z kwalifikacją stałą. Dzieje się tak prawdopodobnie dlatego, że bieżące przeciążenie zostało utworzone w celu zarówno zwrócenia, jak i ustawienia wartości kluczowych.Zamiast tego możesz użyć:
lub w C ++ 11 możesz użyć
at()
operatora:źródło
map.find(KEY)->second;
nie jest bezpieczny, gdy wartości mapy są ciągami. Ma tendencję do drukowania śmieci, gdy KEY nie zostanie znaleziony.Nie możesz używać
operator[]
na mapie,const
ponieważ ta metoda nie jest,const
ponieważ umożliwia modyfikowanie mapy (możesz przypisać do_map[key]
). Spróbujfind
zamiast tego użyć tej metody.źródło
Niektóre nowsze wersje nagłówków GCC (4.1 i 4.2 na moim komputerze) mają niestandardowe funkcje składowe map :: at (), które są zadeklarowane jako const i generują std :: out_of_range, jeśli klucza nie ma na mapie.
Z odniesienia w komentarzu do funkcji wynika, że zasugerowano to jako nową funkcję składową w bibliotece standardowej.
źródło
Po pierwsze, nie powinieneś używać symboli zaczynających się od _, ponieważ są one zarezerwowane dla implementacji języka / programu zapisującego kompilator. Byłoby bardzo łatwo, gdyby _map był błędem składniowym w czyimś kompilatorze i nie można by obwiniać nikogo poza sobą.
Jeśli chcesz użyć podkreślenia, umieść go na końcu, a nie na początku. Prawdopodobnie popełniłeś ten błąd, ponieważ widziałeś, jak robi to jakiś kod Microsoft. Pamiętaj, że piszą własny kompilator, więc może im się to udać. Mimo wszystko to zły pomysł.
operator [] nie tylko zwraca odniesienie, ale w rzeczywistości tworzy wpis na mapie. Więc nie otrzymujesz tylko mapowania, jeśli nie ma, tworzysz je. Nie tego chciałeś.
źródło
_
jest po prostu błędny. Identyfikatory rozpoczynające się od dwóch podkreślników (__example
) lub identyfikatorów rozpoczynających się od jednego podkreślenia i dużej litery (_Example
) są zastrzeżone._example
nie jest zastrzeżone.