Um Ihre Frage zu beantworten, können Sie einen Iterator verwenden:
std::vector<char> path;
// ...
for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Wenn Sie den Inhalt des Vektors in der for-Schleife ändern möchten, verwenden Sie iteratorstatt const_iterator.
Aber dazu kann noch viel mehr gesagt werden. Wenn Sie nur eine Antwort wünschen, die Sie verwenden können, können Sie hier aufhören. Ansonsten lesen Sie weiter.
auto (C ++ 11) / typedef
Dies ist keine andere Lösung, sondern eine Ergänzung zu der obigen iteratorLösung. Wenn Sie den C ++ 11-Standard (oder höher) verwenden, können Sie das autoSchlüsselwort verwenden, um die Lesbarkeit zu verbessern:
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Der Typ von iwird jedoch nicht konstant sein (dh der Compiler wird std::vector<char>::iteratorals Typ von verwenden i).
In diesem Fall können Sie auch einfach a verwenden typedef(nicht auf C ++ 11 beschränkt und trotzdem sehr nützlich):
typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Zähler
Sie können natürlich einen ganzzahligen Typ verwenden, um Ihre Position in der forSchleife aufzuzeichnen :
for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
Wenn Sie dies tun, ist es besser, die Elementtypen des Containers zu verwenden, sofern diese verfügbar und angemessen sind. Für diesen Job std::vectorwird ein Elementtyp aufgerufen: size_typeDies ist der von der sizeMethode zurückgegebene Typ .
// Path typedef'd to std::vector<char>
for( Path::size_type i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
Warum nicht einfach über die iteratorLösung verwenden? In einfachen Fällen können Sie iteratordies auch tun , aber der Punkt ist, dass die Klasse ein Objekt ist, das für diese Aufgabe für kompliziertere Objekte entwickelt wurde, bei denen diese Lösung nicht ideal ist.
bereichsbasierte for-Schleife (C ++ 11)
Siehe Jefffreys Lösung . In C ++ 11 (und höher) können Sie die neue bereichsbasierte forSchleife verwenden, die folgendermaßen aussieht:
for (auto i: path)
std::cout << i << ' ';
Da pathes sich (explizit std::vector<char>) um einen Vektor von Elementen handelt , ist das Objekt ivom Typ des Elements des Vektors (dh explizit vom Typ char). Das Objekt ihat einen Wert, der eine Kopie des tatsächlichen Elements im pathObjekt ist. Somit ibleiben nicht alle Änderungen in der Schleife an sich erhalten path. Wenn Sie darüber hinaus die Tatsache erzwingen möchten , dass Sie nicht in der Lage sein wollen , den kopierten Wert zu ändern , iin der Schleife, können Sie die Art der Gewalt izu sein const charwie folgt aus :
for (const auto i: path)
std::cout << i << ' ';
Wenn Sie die Elemente in ändern möchten path, können Sie eine Referenz verwenden:
for (auto& i: path)
std::cout << i << ' ';
und selbst wenn Sie nicht ändern möchten, sollten Sie path, wenn das Kopieren von Objekten teuer ist, eine const-Referenz verwenden, anstatt nach Wert zu kopieren:
for (const auto& i: path)
std::cout << i << ' ';
std :: copy
Siehe Joshuas Antwort . Sie können den STL-Algorithmus verwenden, std::copyum den Vektorinhalt in den Ausgabestream zu kopieren. Dies ist eine elegante Lösung, wenn Sie damit vertraut sind (und außerdem ist sie sehr nützlich, nicht nur in diesem Fall, wenn Sie den Inhalt eines Vektors drucken).
std :: for_each
Siehe Max 'Lösung . Die Verwendung std::for_eachist für dieses einfache Szenario übertrieben, aber eine sehr nützliche Lösung, wenn Sie mehr als nur auf dem Bildschirm drucken möchten: Mit der Option std::for_eachkönnen Sie jede (sinnvolle) Operation am Vektorinhalt ausführen.
Überladung ostream :: operator <<
Siehe Chris 'Antwort , dies ist eher eine Ergänzung zu den anderen Antworten, da Sie bei der Überladung noch eine der oben genannten Lösungen implementieren müssen. In seinem Beispiel verwendete er einen Zähler in einer forSchleife. So können Sie beispielsweise schnell Joshuas Lösung verwenden :
template <typename T>
std::ostream& operator<< (std::ostream& out, const std::vector<T>& v) {
if ( !v.empty() ) {
out << '[';
std::copy (v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
out << "\b\b]";
}
return out;
}
Die Verwendung einer der anderen Lösungen sollte unkompliziert sein.
Fazit
Jede der hier vorgestellten Lösungen funktioniert. Es liegt an Ihnen und dem Code, auf dem man der "Beste" ist. Alles, was detaillierter ist, bleibt wahrscheinlich am besten für eine andere Frage übrig, bei der die Vor- und Nachteile richtig bewertet werden können. Aber wie immer wird die Benutzerpräferenz immer eine Rolle spielen: Keine der vorgestellten Lösungen ist falsch, aber einige sehen für jeden einzelnen Codierer besser aus.
Nachtrag
Dies ist eine erweiterte Lösung einer früheren, die ich veröffentlicht habe. Da dieser Beitrag immer mehr Beachtung fand, habe ich mich entschlossen, ihn zu erweitern und auf die anderen hervorragenden Lösungen zu verweisen, die hier veröffentlicht wurden. Mein ursprünglicher Post hatte eine Bemerkung, dass erwähnt , wenn Sie wurden auf Modifizieren Ihr Vektor in einer Absicht , forSchleife , dann gibt es zwei , bereitgestellt durch Methoden std::vectorzum Zugriffselement: std::vector::operator[]die Grenzen nicht tun prüfen, und std::vector::atdie tun ausführen Überprüfung Grenzen. Mit anderen Worten, atwird geworfen, wenn Sie versuchen, auf ein Element außerhalb des Vektors zuzugreifen, und operator[]dies nicht tun würden. Ich habe diesen Kommentar ursprünglich nur hinzugefügt, um etwas zu erwähnen, von dem es nützlich sein könnte, zu wissen, ob dies bereits jemand getan hat. Und ich sehe jetzt keinen Unterschied. Daher dieser Nachtrag.