2009-03-22 5 views
162

Also, ich schrieb eine Menge Code, der auf Elemente in einem STL-Vektor durch index [] zugreift, aber jetzt muss ich nur einen Teil des Vektors kopieren. Es sieht aus wie vector.insert(pos, first, last) ist die Funktion, die ich will ... außer ich habe nur erste und letzte als Ints. Gibt es eine nette Möglichkeit, einen Iterator für diese Werte zu bekommen?C++ STL-Vektoren: Iterator aus dem Index abrufen?

+1

Siehe auch: http://stackoverflow.com/q/2152986/365102 –

Antwort

234

Try this:

vector<Type>::iterator nth = v.begin() + index; 
+4

Im Allgemeinen können Sie die gleiche Arithmetik mit STL Iteratoren verwenden, als mit Zeiger. Sie sind so konzipiert, dass sie bei Verwendung von STL-Algorithmen austauschbar sind. –

+14

@VincentRobert: Anders herum. Zeiger sind gültige Implementierungen von STL-Zufalls-Iteratoren, der leistungsstärksten Kategorie. Andere weniger leistungsfähige Kategorien wie Vorwärtsiteratoren unterstützen jedoch nicht die gleiche Arithmetik. – MSalters

+0

Ich möchte meine fünf Cent zu dieser Antwort hinzufügen und empfehlen 'std :: next (v.begin(), Index)' – stryku

75

Weise erwähnt von @dirkgently (v.begin() + index) schön und schnell für Vektoren

aber std::advance(v.begin(), index) allgemeinste Art und Weise und für den Direktzugriff Iteratoren funktioniert auch konstante Zeit.

EDIT
Unterschiede in der Nutzung:

std::vector<>::iterator it = (v.begin() + index); 

oder

std::vector<>::iterator it = v.begin(); 
std::advance(it, index); 

nach @litb Notizen hinzugefügt.

+0

nicht std :: advance erfordern einen nicht-const-Iterator als erstes Argument? – goldPseudo

+0

entsprechend - http://www.sgi.com/tech/stl/advance.html - nein. – bayda

+0

Sie können std :: advance mit const und non-const Iteratoren verwenden – bayda

-3

Tatsächliche std :: vector sind dazu bestimmt, bei Bedarf als C-Registerkarte verwendet zu werden. (C++ Standard-Anforderungen, die für die Vektor Umsetzung, soweit ich weiß - replacement for array in Wikipedia) Zum Beispiel es vollkommen legal ist, diese folowing zu tun, nach mir:

int main() 
{ 

void foo(const char *); 

sdt::vector<char> vec; 
vec.push_back('h'); 
vec.push_back('e'); 
vec.push_back('l'); 
vec.push_back('l'); 
vec.push_back('o'); 
vec.push_back('/0'); 

foo(&vec[0]); 
} 

Natürlich entweder foo muss die Adresse nicht kopieren übergeben als ein Parameter und speichern Sie es irgendwo, oder Sie sollten in Ihrem Programm sicherstellen, nie ein neues Element in Vec schieben, oder fordert seine Kapazität zu ändern. Oder Risiko Segmentation fault ...

daher in Ihrem exemple führt es zu

vector.insert(pos, &vec[first_index], &vec[last_index]); 
+0

Ich frage mich, warum sie sich entschieden haben, zu Iteratoren zu abstrahieren, wenn sie nur Zeiger sind ... sie verbergen diese Fähigkeiten im Wesentlichen. – mpen

+0

Für die Consistency? Da es Ihnen ermöglichen würde, Vektorinstanz einfach für jede andere Art von Container in Ihrem Code zu entfernen. –

+4

& vec [i] liefert einen Zeiger, der nicht unbedingt mit dem Vektor <> :: iterator kompatibel ist. vec.begin() + Ich habe immer noch den Vorteil, unabhängig davon zu sein, welcher Iterator in Ihrer Bibliothek definiert ist - einschließlich geprüfter Iteratoren im Debug-Modus. Wenn Sie also keinen Zeiger benötigen (z. B. für E/A), sollten Sie Iteratoren immer bevorzugen. – sellibitze

7

Oder Sie können std::advance

vector<int>::iterator i = L.begin(); 
advance(i, 2); 
33

auch verwenden; auto it = std::next(v.begin(), index);

Update: Benötigt eine C++ 11x kompatible Compiler

+2

Es sollte beachtet werden, dass dies der C++ 11 Weg ist! std :: next entspricht std :: advance. Die Verwendung dieser Funktionen anstelle der Verwendung von Arithmetik macht das Tauschen von Containertypen sehr viel einfacher. Funktioniert sogar mit c-arrays afaik, genau wie std :: begin und std :: end. – Zoomulator

+2

Es sollte auch beachtet werden, dass std :: advance von einem Idioten entworfen wird, da es eine Referenz als Ausgabe und nicht den Rückgabewert verwendet. –

+1

für (auto it = Anfang (c); it! = Ende (c); Fortschritt (it, n)) {...} – Zoomulator