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 iteratorplutô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 iteratorsolution ci-dessus . Si vous utilisez la norme C ++ 11 (ou ultérieure), vous pouvez utiliser le automot clé pour améliorer la lisibilité:
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Mais le type de isera non-const (ie, le compilateur utilisera std::vector<char>::iteratorcomme 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 forboucle:
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::vectora un type de membre appelé size_typepour ce travail: c'est le type renvoyé par la sizemé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 iteratorsolution? Pour les cas simples, vous pourriez aussi bien, mais le fait est que la iteratorclasse 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 forboucle basée sur une plage , qui ressemble à ceci:
for (auto i: path)
std::cout << i << ' ';
Puisque pathest un vecteur d'éléments (explicitement std::vector<char>), l'objet iest de type de l'élément du vecteur (c'est-à-dire, explicitement, il est de type char). L'objet ia une valeur qui est une copie de l'élément réel dans l' pathobjet. Ainsi, toutes les modifications apportées à ila boucle ne sont pas conservées en pathsoi. De plus, si vous voulez faire respecter le fait que vous ne voulez pas être en mesure de changer la valeur copiée de ila boucle, vous pouvez forcer le type de iêtre const charcomme 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::copypour 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_eachest 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_eachvous 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 forboucle. 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 forboucle , puis il y a deux méthodes fournies par std::vectordes éléments d'accès: std::vector::operator[]qui ne fait pas vérification de limites, et std::vector::atqui n'effectue la vérification des limites. En d'autres termes, atlancera 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.