algoritmos de STL e const_iterators
Pergunta
Hoje escrevi uma pequena predicado para encontrar símbolos combinando em um recipiente.
Mas eu sou confrontado com um problema: eu quero usar esse predicado em uma chamada std::find_if
dentro de um const-método de uma classe, procurando em um recipiente que é um membro desta classe
Mas eu só notei que nem std::find
nem std::find_if
são capazes de operar em const_iterators
!
Eu verifiquei em algumas referências C ++ e parece que não há nenhuma versão do std::find
ou std::find_if
que aceitar const_iterators
/ retorno. Eu simplesmente não consigo entender o porquê, já que desde que eu vi, não há nenhuma maneira que estes algoritmos pode modificar o objeto referenciado pelo iterador.
Aqui está como está documentado std::find
na implementação SGI:
Retorna a primeira iteração i na intervalo [first, last) tal que * i == valor. Devoluções durar se tal iterator existe.
Solução
std::find
e std::find_if
definitivamente pode operar em *::const_iterator
para um determinado recipiente. Você por acaso olhar para as assinaturas dessas funções, e entendendo mal eles?
template <class InputIterator, class Type>
InputIterator find(InputIterator first, InputIterator last, const Type& val);
Note que InputIterator
aqui é apenas um nome de um parâmetro de tipo de modelo, e qualquer const_iterator
a satisfazer os requisitos para isso.
Ou, talvez, você está confundindo const_iterator
(ou seja, um iterador referência a um valor const) com um iterador const
(ou seja, um iterador que é em si const
)?
Outras dicas
std::find
e std::find_if
ambos tomam o tipo de iterador como um parâmetro de modelo, então eles certamente pode operar em const_iterators
. Apenas para um exemplo rápido:
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> x;
std::fill_n(std::back_inserter(x), 20, 2);
x.push_back(3);
std::vector<int>::const_iterator b = x.begin();
std::vector<int>::const_iterator e = x.end();
std::vector<int>::const_iterator p = std::find(b, e, 3);
std::cout << *p << " found at position: " << std::distance(b, p) << "\n";
return 0;
}
Isto deve ser aceito por qualquer compilador C ++ funcionando corretamente, e produzir resultados como:
3 encontrado na posição: 20
Acabei de ter o mesmo problema. Eu tinha uma função membro que estava chamando find_if
em um vector membro, eo compilador me deu um erro quando eu tentei fazer a função de membro const
. Descobriu-se que esta foi porque eu estava atribuindo o valor de retorno de find_if
a um iterator
vez de const_iterator
. O fez com que o compilador para supor que os parâmetros de find_if
também deve ser iterator
vez de const_iterator
, o que não poderia começar a partir do vector membro const
.
Se por acaso você está aqui pela mesma razão que eu:
error: no matching function for call to ‘find(std::vector<int>::const_iterator, std::vector<int>::const_iterator, int)’
Ele não tem nada a ver com const_iterator
s. Você provavelmente só esqueceu de #include <algorithm>
: -)
Eu só tinha um problema com este código:
std::string str;
std::string::const_iterator start = str.begin();
std::string::const_iterator match = std::find(start, str.end(), 'x');
O erro foi "sem sobrecarga de correspondência para std :: find".
A correção que eu precisava era utilização cend (). É confuso que cbegin () não é necessário, eu não sei por que a conversão é bem (implicitamente) e não para o final () como um parâmetro de função.