Los algoritmos de STL y const_iterators
Pregunta
Hoy me escribió un pequeño predicado a encontrar símbolos iguales en un recipiente.
Pero me enfrento a un problema:Quiero usar este predicado en una std::find_if
llame dentro de una const-método de una clase, la búsqueda en un contenedor que es un miembro de esta clase.
Pero me di cuenta de que ni std::find
ni std::find_if
son capaces de operar sobre const_iterators
!
He comprobado en algunos C++ referencias y parece que no hay versión de std::find
o std::find_if
que aceptar/retorno const_iterators
.Simplemente no puedo entender por qué, ya que por lo que he visto, no hay manera de que estos algoritmos se podía modificar el objeto referenciado por el iterador.
Aquí es cómo se documenta std::find
en el SGI de la aplicación:
Devuelve el primer iterador i en el rango [primero, ultimo) tales que *i == valor.Retorna el último si no iterador existe.
Solución
std::find
y std::find_if
sin duda puede operar en *::const_iterator
para un contenedor.Son por casualidad buscando en las firmas de esas funciones, y la incomprensión de ellos?
template <class InputIterator, class Type>
InputIterator find(InputIterator first, InputIterator last, const Type& val);
Tenga en cuenta que InputIterator
aquí es sólo un nombre de una plantilla de tipo de parámetro, y cualquier const_iterator
se cumplen los requisitos para ello.
O, tal vez, estás confuso const_iterator
(es decir,un iterador que hace referencia a una constante de valor) con un const
iterator (es decir,un iterador que es en sí mismo const
)?
Otros consejos
std::find
y std::find_if
los dos tienen el tipo de iterador como un parámetro de plantilla, por lo que la mayoría sin duda puede operar en const_iterators
.Sólo un ejemplo 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;
}
Este debe ser aceptado por cualquier funcione correctamente compilador de C++, y producir resultados como:
3 que se encuentra en la posición:20
Acabo de tener el mismo problema. Tenía una función miembro que estaba llamando a find_if
en un vector miembro, y el compilador me dio un error cuando intenté hacer que la función miembro const
. Resultó que esto se debía a que estaba asignando el valor de retorno de iterator
a un const_iterator
en lugar de <=>. Esto provocó que el compilador suponga que los parámetros de <=> también deben ser <=> en lugar de <=>, lo que no pudo obtener del vector de miembros <=>.
Si por casualidad estás aquí por el mismo motivo que yo:
error: no matching function for call to ‘find(std::vector<int>::const_iterator, std::vector<int>::const_iterator, int)’
No tiene nada que ver con const_iterator
s. Probablemente te hayas olvidado de #include <algorithm>
:-)
Acabo de tener un problema con este código:
std::string str;
std::string::const_iterator start = str.begin();
std::string::const_iterator match = std::find(start, str.end(), 'x');
El error fue " no hay sobrecarga coincidente para std :: find " ;.
La solución que necesitaba era usar cend (). Es confuso que cbegin () no sea necesario, no estoy seguro de por qué esa conversión está bien (implícitamente) y no para el final () como un parámetro de función.