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.

Foi útil?

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_iterators. 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top