O código a seguir diz que passar o mapa como const
no operator[]
método descarta os qualificadores:
#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;
}
É por causa da possível alocação que ocorre no acesso ao mapa? Nenhuma função com acessos de mapa pode ser declarada const?
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
Respostas:
std::map
'soperator []
não é declarado comoconst
e não pode ser devido ao seu comportamento:Como resultado, sua função não pode ser declarada
const
e use a do mapaoperator[]
.std::map
Afind()
função de permite que você procure uma chave sem modificar o mapa.find()
retorna umiterator
, ouconst_iterator
para umstd::pair
contendo a chave (.first
) e o valor (.second
).No C ++ 11, você também pode usar
at()
parastd::map
. Se o elemento não existe, a função lança umastd::out_of_range
exceção, em contraste comoperator []
.fonte
operator[]
(por exemplofoo[bar] = baz
) e rvalueoperator[]
(por exemplox = foo[bar]
) - o último certamente poderia ser const.Desde a
operator[]
não tem uma sobrecarga qualificada const, não pode ser usado com segurança em uma função qualificada const. Isso provavelmente ocorre porque a sobrecarga atual foi construída com o objetivo de retornar e definir valores-chave.Em vez disso, você pode usar:
ou, em C ++ 11, você pode usar o
at()
operador:fonte
map.find(KEY)->second;
não é seguro quando os valores do mapa são strings. Ele tende a imprimir lixo quando a CHAVE não é encontrada.Você não pode usar
operator[]
em um mapaconst
porque esse método não éconst
, pois permite que você modifique o mapa (você pode atribuir a_map[key]
). Tente usar ofind
método.fonte
Algumas versões mais recentes dos cabeçalhos GCC (4.1 e 4.2 em minha máquina) têm funções de membro não padrão map :: at () que são declaradas const e lançam std :: out_of_range se a chave não estiver no mapa.
A partir de uma referência no comentário da função, parece que isso foi sugerido como uma nova função de membro na biblioteca padrão.
fonte
Primeiro, você não deve usar símbolos que começam com _ porque eles são reservados para a implementação da linguagem / redator do compilador. Seria muito fácil para _map ser um erro de sintaxe no compilador de alguém, e você não teria ninguém para culpar a não ser você mesmo.
Se você quiser usar um sublinhado, coloque-o no final, não no início. Você provavelmente cometeu esse erro porque viu algum código da Microsoft fazendo isso. Lembre-se de que eles escrevem seu próprio compilador, então podem ser capazes de se safar. Mesmo assim, é uma má ideia.
o operador [] não apenas retorna uma referência, ele realmente cria a entrada no mapa. Portanto, você não está apenas obtendo um mapeamento, se não houver nenhum, você está criando um. Não foi isso que você pretendeu.
fonte
_
está simplesmente errado. Identificadores que começam com dois sublinhados (__example
) ou identificadores que começam com um sublinhado e uma letra maiúscula (_Example
) são reservados._example
não é reservado.