Kann mir jemand sagen, wie man den Iterator um 2 erhöht?
iter++
ist verfügbar - muss ich tun iter+2
? Wie kann ich das erreichen?
c++
visual-c++
stl
iterator
Süß
quelle
quelle
Antworten:
std::advance( iter, 2 );
Diese Methode funktioniert für Iteratoren, die keine Iteratoren mit wahlfreiem Zugriff sind, kann jedoch durch die Implementierung so spezialisiert werden, dass sie nicht weniger effizient ist als
iter += 2
bei Verwendung mit Iteratoren mit wahlfreiem Zugriff.quelle
http://www.cplusplus.com/reference/std/iterator/advance/
std::advance(it,n);
Dabei ist n in Ihrem Fall 2.
Das Schöne an dieser Funktion ist, dass wenn "es" ein Iterator mit wahlfreiem Zugriff ist, das schnelle
Operation wird verwendet (dh Vektor <,,> :: Iterator). Ansonsten wird es gerendert
for(int i = 0; i < n; i++) ++it;
(dh Liste <..> :: Iterator)
quelle
Wenn Sie keinen veränderbaren Wert eines Iterators haben oder eine Kopie eines bestimmten Iterators erhalten möchten (wobei der ursprüngliche unverändert bleibt), verfügt C ++ 11 über neue Hilfsfunktionen -
std::next
/std::prev
:std::next(iter, 2); // returns a copy of iter incremented by 2 std::next(std::begin(v), 2); // returns a copy of begin(v) incremented by 2 std::prev(iter, 2); // returns a copy of iter decremented by 2
quelle
map<string,string>::iterator iter; for(iter = variations.begin(); iter != variations.end(); iter++) { map<string,string>::iterator it_tmp = std::next(iter, 1); // increment by 1 it_tmp = std::next(iter, 2); // increment by 2 }
Wird der Iter um 2 erhöht? oder iter wird nur it_tmp beeinflussen?Sie können den Operator 'Zuweisung durch Addition' verwenden
quelle
Wenn Sie nicht wissen, ob Sie genügend nächste Elemente in Ihrem Container haben oder nicht, müssen Sie zwischen jedem Inkrement das Ende Ihres Containers überprüfen. Weder ++ noch std :: advanced werden dies für Sie tun.
if( ++iter == collection.end()) ... // stop if( ++iter == collection.end()) ... // stop
Sie können sogar Ihre eigene gebundene sichere Vorausfunktion ausführen.
Wenn Sie sicher sind, dass Sie das Ende nicht überschreiten, ist std :: advanced (iter, 2) die beste Lösung.
quelle
Wir können sowohl std :: advanced als auch std :: next verwenden , aber es gibt einen Unterschied zwischen den beiden.
advance
ändert sein Argument und gibt nichts zurück. So kann es verwendet werden als:vector<int> v; v.push_back(1); v.push_back(2); auto itr = v.begin(); advance(itr, 1); //modifies the itr cout << *itr<<endl //prints 2
next
gibt eine geänderte Kopie des Iterators zurück:vector<int> v; v.push_back(1); v.push_back(2); cout << *next(v.begin(), 1) << endl; //prints 2
quelle
Angenommen, die Listengröße ist möglicherweise nicht ein Vielfaches der Schritte, die Sie gegen Überlauf schützen müssen:
static constexpr auto step = 2; // Guard against invalid initial iterator. if (!list.empty()) { for (auto it = list.begin(); /*nothing here*/; std::advance(it, step)) { // do stuff... // Guard against advance past end of iterator. if (std::distance(it, list.end()) > step) break; } }
Abhängig von der Implementierung der Sammlung kann die Entfernungsberechnung sehr langsam sein. Unten ist optimal und besser lesbar. Der Abschluss kann in eine Dienstprogrammvorlage geändert werden, deren Listenendwert als const-Referenz übergeben wird:
const auto advance = [&](list_type::iterator& it, size_t step) { for (size_t i = 0; it != list.end() && i < step; std::next(it), ++i); }; static constexpr auto step = 2; for (auto it = list.begin(); it != list.end(); advance(it, step)) { // do stuff... }
Wenn es keine Schleife gibt:
static constexpr auto step = 2; auto it = list.begin(); if (step <= list.size()) { std::advance(it, step); }
quelle
Die sehr einfache Antwort:
++++iter
Die lange Antwort:
Eigentlich sollte man gewöhnen Schreiben
++iter
stattiter++
. Letzterer muss den alten Wert zurückgeben (eine Kopie davon), der sich vom neuen Wert unterscheidet. Das braucht Zeit und Raum.Beachten Sie, dass das Präfix increment (
++iter
) einen l-Wert annimmt und einen l-Wert zurückgibt, während das postfix-Inkrement (iter++
) einen l-Wert annimmt und einen r-Wert zurückgibt.quelle
iter
es sich um einen Rohzeiger handelt (was einige Iteratortypen sein können).++it; ++it;
wäre in Ordnung.