c ++ - Gurus:
Es gibt einige nützliche C ++ stl-Algorithmen wie Suchen oder Suchen. Es scheint jedoch, dass sie nur einen einzigen Interator zurückgeben.
Was ist, wenn ich einen SQL-Stil für einen STL-Container auswählen möchte? sagen wir, ein Vektor (könnte zur Liste oder Karte erweitert werden). etwas wie
%Vor%Die Ausgabe sollte ein Bereich sein, etwa ein std :: pair, das dem Rückgabewert der Methoden in boost :: multi-index
ähneltGibt es sowas in stl? oder irgendwelche feste Libraries ähnlich?
Sie haben grundsätzlich zwei Ansätze:
1) Was Sie in einem Kommentar oben sagen, schreiben Sie (Iteratoren zeigen auf) die Ergebnisse in einen Container von Iteratoren. Das wird ungefähr so aussehen:
%Vor%Dann nennst du es wie folgt:
%Vor% Sie könnten select_iterators
in anderen Algorithmen definieren, indem Sie copy_if
und boost::counting_iterator
verwenden, aber ich denke nicht, dass es sich lohnt, wenn die direkte Implementierung so einfach ist. Es würde aussehen wie:
2) Anstatt alle Werte vorab zu testen und die Ergebnisse irgendwo zu schreiben, definieren Sie einen Iterator, der bei jeder Inkrementierung über den ursprünglichen Bereich hinausgeht, bis er die nächste Übereinstimmung findet. Boost bietet zwei Möglichkeiten, boost::filter_iterator
und boost::adaptors::filter
. Du könntest also schreiben:
Was auch immer Sie mit Ihren Ergebnissen tun möchten, Sie können von results.begin()
nach results.end()
iterieren, als wäre es ein Container. Es ist kein Container, es erfüllt nicht die gesamte Containerschnittstelle. Es erfüllt eine von Boost definierte Schnittstelle namens Range, die "über iteriert werden kann". Es ist eigentlich nur eine gefilterte Ansicht von myfoos
, also wird kein Foo
-Objekt kopiert oder verschoben.
Wenn Sie Ihren Vektor ändern können std :: partition wäre die Wahl. Hier, wie würdest du es nennen:
%Vor% Sie befinden sich zwischen v.begin()
und p
.
Sie könnten nach A boost::range
boost::range
ist effektiv ein Paar von Iteratoren, die einen Bereich von Elementen eines Containers begrenzen. Die Bibliothek enthält verschiedene Algorithmen, die einen Bereich aus einem Bereich zurückgeben (z. B. den Bereich äquivalenter Werte im Container mit einem vom Benutzer bereitgestellten Äquivalenzfunktor).
Dinge zu beachten:
1.) Sie haben angegeben, dass Ihr Container von iterator
und nicht von const_iterator
sein soll. Der Typ entspricht dem Anfangs- und Endbereich, den Sie an die Funktion übergeben. Der Typ ist beispielsweise const_iterator
für const
containers, er wird auch const_iterator
sein, wenn Sie vector::cbegin
und vector::cend
verwenden, und er wird nicht kompiliert, wenn Sie andere Iteratoren wie vector::begin
verwenden. und vector::cend
.
2.) Vektoren verlieren oft ihre Iterator-Gültigkeit, also seien Sie vorsichtig bei der Verwendung dieser Iteratoren. Wenn Sie beispielsweise zum Vektor hinzufügen, könnte jeder von dieser Funktion zurückgegebene Iterator ungültig sein. Um dies zu verhindern, verwenden Sie entweder einen anderen Container (z. B. Liste) oder verwenden Sie vector::reserve
.
3.) Der Vorwärts-Iterator muss etwas sein, das ++ unterstützt, und wenn dereferenziert wird, hat es denselben Typ wie InputIterator (z. B. vector<int>::iterator
). Es muss auch ein gültiger Iterator bleiben, nachdem es inkrementiert wurde, oder die Funktion wäre bedeutungslos. Der Ausgabe-Iterator muss an einen Platz mit genügend Platz für alle gefundenen Iteratoren gehen, um pred
zu setzen. Wenn Sie den Speicherplatz nicht im Voraus kennen, können Sie std::back_inserter
von <iterator>
mit einem Container verwenden, für den container::push_back
definiert ist, und dieser wird nach Bedarf erweitert.
Hier ist ein Test der Funktion für Sie zu verstehen, wie es funktioniert.
%Vor%