Pour répondre à votre question, vous pouvez utiliser un itérateur:
std::vector<char> path;
// ...
for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Si vous souhaitez modifier le contenu du vecteur dans la boucle for, utilisez iterator
plutôt que const_iterator
.
Mais il y a beaucoup plus à dire à ce sujet. Si vous voulez juste une réponse que vous pouvez utiliser, vous pouvez vous arrêter ici; sinon, lisez la suite.
auto (C ++ 11) / typedef
Ce n'est pas une autre solution, mais un complément à la iterator
solution ci-dessus . Si vous utilisez la norme C ++ 11 (ou ultérieure), vous pouvez utiliser le auto
mot clé pour améliorer la lisibilité:
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Mais le type de i
sera non-const (ie, le compilateur utilisera std::vector<char>::iterator
comme type de i
).
Dans ce cas, vous pourriez tout aussi bien utiliser un typedef
(non limité à C ++ 11, et très utile à utiliser quand même):
typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
compteur
Vous pouvez bien sûr utiliser un type entier pour enregistrer votre position dans la for
boucle:
for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
Si vous comptez le faire, il est préférable d'utiliser les types de membres du conteneur, s'ils sont disponibles et appropriés. std::vector
a un type de membre appelé size_type
pour ce travail: c'est le type renvoyé par la size
méthode.
// Path typedef'd to std::vector<char>
for( Path::size_type i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
Pourquoi ne pas simplement l'utiliser sur la iterator
solution? Pour les cas simples, vous pourriez aussi bien, mais le fait est que la iterator
classe est un objet conçu pour faire ce travail pour des objets plus compliqués où cette solution ne sera pas idéale.
basé sur une plage pour la boucle (C ++ 11)
Voir la solution de Jefffrey . En C ++ 11 (et versions ultérieures), vous pouvez utiliser la nouvelle for
boucle basée sur une plage , qui ressemble à ceci:
for (auto i: path)
std::cout << i << ' ';
Puisque path
est un vecteur d'éléments (explicitement std::vector<char>
), l'objet i
est de type de l'élément du vecteur (c'est-à-dire, explicitement, il est de type char
). L'objet i
a une valeur qui est une copie de l'élément réel dans l' path
objet. Ainsi, toutes les modifications apportées à i
la boucle ne sont pas conservées en path
soi. De plus, si vous voulez faire respecter le fait que vous ne voulez pas être en mesure de changer la valeur copiée de i
la boucle, vous pouvez forcer le type de i
être const char
comme ceci:
for (const auto i: path)
std::cout << i << ' ';
Si vous souhaitez modifier les éléments dans path
, vous pouvez utiliser une référence:
for (auto& i: path)
std::cout << i << ' ';
et même si vous ne souhaitez pas modifier path
, si la copie d'objets est coûteuse, vous devez utiliser une référence const au lieu de copier par valeur:
for (const auto& i: path)
std::cout << i << ' ';
std :: copy
Voir la réponse de Joshua . Vous pouvez utiliser l'algorithme STL std::copy
pour copier le contenu vectoriel sur le flux de sortie. C'est une solution élégante si vous êtes à l'aise avec elle (et d'ailleurs, elle est très utile, pas seulement dans ce cas d'impression du contenu d'un vecteur).
std :: for_each
Voir la solution de Max . L'utilisation std::for_each
est exagérée pour ce scénario simple, mais c'est une solution très utile si vous vouliez faire plus que simplement imprimer à l'écran: l'utilisation std::for_each
vous permet d'effectuer n'importe quelle opération (raisonnable) sur le contenu du vecteur.
surcharge ostream :: operator <<
Voir la réponse de Chris , c'est plus un complément aux autres réponses puisque vous devrez toujours implémenter l'une des solutions ci-dessus dans la surcharge. Dans son exemple, il a utilisé un compteur en for
boucle. Par exemple, voici comment utiliser rapidement la solution de Joshua :
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;
}
L'utilisation de l'une des autres solutions doit être simple.
conclusion
Toutes les solutions présentées ici fonctionneront. C'est à vous et au code sur lequel on est le "meilleur". Tout ce qui est plus détaillé est probablement préférable de laisser une autre question où les avantages / inconvénients peuvent être correctement évalués; mais comme toujours, la préférence de l'utilisateur jouera toujours un rôle: aucune des solutions présentées n'est fausse, mais certaines seront plus jolies pour chaque codeur individuel.
Addenda
Il s'agit d'une solution étendue d'une précédente que j'ai publiée. Étant donné que ce message continuait à attirer l'attention, j'ai décidé de l'étendre et de faire référence aux autres excellentes solutions publiées ici. Mon message original avait une remarque qui dit que si vous aviez l' intention sur la modification de votre vecteur dans une for
boucle , puis il y a deux méthodes fournies par std::vector
des éléments d'accès: std::vector::operator[]
qui ne fait pas vérification de limites, et std::vector::at
qui n'effectue la vérification des limites. En d'autres termes, at
lancera si vous essayez d'accéder à un élément en dehors du vecteur et operator[]
ne le ferait pas. Je n'ai ajouté ce commentaire, à l'origine, que pour mentionner quelque chose qu'il pourrait être utile de savoir si quelqu'un ne l'a pas déjà fait. Et je ne vois aucune différence maintenant. D'où cet addendum.