STL-Algorithmen und const_iterators
Frage
Heute habe ich ein kleines Prädikat, um passende Symbole in einem Behälter zu finden.
Aber ich bin zu einem Problem. Ich möchte dieses Prädikat verwenden, in einem std::find_if
Anruf innerhalb einer const-Methode einer Klasse, in einem Container zu suchen, die ein Mitglied dieser Klasse ist
Aber ich habe gerade bemerkt, dass weder std::find
noch std::find_if
der Lage ist, auf const_iterators
zu bedienen!
überprüfte ich auf einige C ++ Referenzen und es scheint, gibt es keine Version von std::find
oder std::find_if
, die / return const_iterators
akzeptieren. Ich kann einfach nicht verstehen, warum, denn von dem, was ich gesehen habe, gibt es keine Möglichkeit, dass diese Algorithmen, um das durch den Iterator referenzierte Objekt ändern könnten.
Hier ist, wie ist std::find
in der SGI Implementierung dokumentiert:
Gibt das erste Iterator i in der Bereich [first, last), so daß * i == Wert. Gibt zuletzt, wenn keine solche Iterator besteht.
Lösung
std::find
und std::find_if
kann auf jeden Fall auf *::const_iterator
für einen bestimmten Behälter betreiben. Sind Sie zufällig auf die Unterschriften dieser Funktionen suchen, und Missverständnissen sie?
template <class InputIterator, class Type>
InputIterator find(InputIterator first, InputIterator last, const Type& val);
Beachten Sie, dass hier InputIterator
ist nur ein Name eines Template-Typ Parameter und jede const_iterator
die Anforderungen dafür erfüllen.
Oder vielleicht Sie verwirrend const_iterator
(das heißt ein Iterator einen const Wert Referenzierung) mit einem const
Iterator (das heißt ein Iterator, die selbst const
)?
Andere Tipps
std::find
und beide std::find_if
nehmen Sie die Iteratortyp als Template-Parameter, so dass sie mit Sicherheit können auf const_iterators
arbeiten. Nur für ein kurzes Beispiel:
#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;
}
Dies sollte durch eine gut funktionierende C ++ Compiler akzeptiert werden und zu Ergebnissen führen wie:
3 an Position gefunden: 20
Ich hatte gerade das gleiche Problem. Ich hatte eine Member-Funktion, die auf einem Mitglied Vektor ruft find_if
, und der Compiler gab mir einen Fehler, wenn ich versuchte, die Member-Funktion const
machen. Es stellte sich heraus, dass dies, weil ich den Rückgabewert von find_if
zu einem iterator
statt const_iterator
Zuordnung wurde. Das verursacht der Compiler davon ausgehen, dass die Parameter der find_if
müssen auch statt iterator
const_iterator
werden, die sie nicht aus dem const
Mitglied Vektor bekommen konnte.
Wird durch Zufall sind Sie hier aus dem gleichen Grund wie ich:
error: no matching function for call to ‘find(std::vector<int>::const_iterator, std::vector<int>::const_iterator, int)’
Es hat nichts mit const_iterator
s zu tun. Sie haben wahrscheinlich nur vergessen #include <algorithm>
: -)
Ich hatte nur ein Problem mit diesem Code:
std::string str;
std::string::const_iterator start = str.begin();
std::string::const_iterator match = std::find(start, str.end(), 'x');
Der Fehler war "keine passende Überlastung für std :: find".
Das Update war ich brauchte zu verwenden cend (). Es ist verwirrend, dass CBEGIN () nicht erforderlich ist, ich bin nicht sicher, warum, dass die Umwandlung in Ordnung ist (implizit) und nicht für das Ende () als Funktionsparameter.