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 iterator
statt 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 iterator
Lösung. Wenn Sie den C ++ 11-Standard (oder höher) verwenden, können Sie das auto
Schlüsselwort verwenden, um die Lesbarkeit zu verbessern:
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Der Typ von i
wird jedoch nicht konstant sein (dh der Compiler wird std::vector<char>::iterator
als 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 for
Schleife 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::vector
wird ein Elementtyp aufgerufen: size_type
Dies ist der von der size
Methode 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 iterator
Lösung verwenden? In einfachen Fällen können Sie iterator
dies 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 for
Schleife verwenden, die folgendermaßen aussieht:
for (auto i: path)
std::cout << i << ' ';
Da path
es sich (explizit std::vector<char>
) um einen Vektor von Elementen handelt , ist das Objekt i
vom Typ des Elements des Vektors (dh explizit vom Typ char
). Das Objekt i
hat einen Wert, der eine Kopie des tatsächlichen Elements im path
Objekt ist. Somit i
bleiben 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 , i
in der Schleife, können Sie die Art der Gewalt i
zu sein const char
wie 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::copy
um 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_each
ist 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_each
kö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 for
Schleife. 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 , for
Schleife , dann gibt es zwei , bereitgestellt durch Methoden std::vector
zum Zugriffselement: std::vector::operator[]
die Grenzen nicht tun prüfen, und std::vector::at
die tun ausführen Überprüfung Grenzen. Mit anderen Worten, at
wird 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.