C referência mapa ++ const std :: falha ao compilar
-
22-08-2019 - |
Pergunta
Existe uma razão pela qual passando uma referência a um std::map
como const faz com que o operador [] para pausa? Eu recebo este erro compilador (gcc 4.2) quando eu uso const:
erro: não é páreo para ‘operador []’ em ‘Mapa [nome]’
Aqui está o protótipo da função:
void func(const char ch, std::string &str, const std::map<std::string, std::string> &map);
E, devo mencionar que não há nenhum problema quando eu remover a palavra-chave const
na frente de std::map
.
Se eu tiver sido instruído corretamente, o operador [] vai realmente inserir um novo par para o mapa se não encontrar a chave, o que, naturalmente, explicar por que isso acontece, mas eu não posso imaginar que este jamais seria um comportamento aceitável.
Se houver um método melhor, como o uso de encontrar em vez de [], eu aprecio isso. Eu não consigo obter encontrar ao trabalho, quer embora ... Eu recebo const erros iteradoras incompatíveis.
Solução
Sim, você não pode usar operator[]
. Use find
, mas nota que retorna const_iterator
vez de iterator
:
std::map<std::string, std::string>::const_iterator it;
it = map.find(name);
if(it != map.end()) {
std::string const& data = it->second;
// ...
}
É como com ponteiros. Você não pode int const*
atribuir a int*
. Da mesma forma, você pode const_iterator
não atribuir a iterator
.
Outras dicas
Quando você está usando o operador [], std :: map olhares para o item com determinada chave. Se ele não encontrar nenhum, ele cria-lo. Daí o problema com const.
Use método de encontrar e você vai ficar bem.
Você pode agradar código postal de como você está tentando usar find ()? O caminho certo seria:
if( map.find(name) != map.end() )
{
//...
}
Se você estiver usando C ++ 11, std :: map :: a deve trabalhar para você.
A razão std :: map :: operator [] não funciona é que, no caso da chave que você está procurando não existe no mapa, ele irá inserir um novo elemento usando a chave fornecida e retornar uma referência a ele (veja o link para mais detalhes). Isso não é possível em um const std :: map.
O 'at' método, no entanto, irá lançar uma exceção se a chave não existe. Dito isto, é provavelmente uma boa idéia para verificar a existência da chave usando o método std :: map :: find antes de tentar acessar o elemento usando o 'at' método.
Provavelmente porque não há nenhum operador const [] em std :: map. operador [] irá adicionar o elemento que você está procurando se não encontrá-lo. Portanto, use o método find () se você quiser pesquisar sem a possibilidade de adicionar.
Para a sua "const incompatíveis iteradoras erros":
find () tem duas sobrecargas:
iterator find ( const key_type& x );
const_iterator find ( const key_type& x ) const;
Meu palpite é que você está recebendo este erro porque você está fazendo algo como a atribuição de um iterador não-const (à esquerda) com o resultado de uma chamada find()
em um mapa const
:
iterator<...> myIter /* non-const */ = myConstMap.find(...)
Isso resultaria em um erro, embora talvez não o que você está vendo.