Solo per rispondere alla tua domanda, puoi usare un iteratore:
std::vector<char> path;
// ...
for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Se si desidera modificare il contenuto del vettore nel ciclo for, utilizzare iterator
invece di const_iterator
.
Ma c'è molto altro da dire al riguardo. Se vuoi solo una risposta che puoi usare, puoi fermarti qui; altrimenti, continua a leggere.
auto (C ++ 11) / typedef
Questa non è un'altra soluzione, ma un supplemento alla iterator
soluzione sopra . Se si utilizza lo standard C ++ 11 (o successivo), è possibile utilizzare la auto
parola chiave per facilitare la leggibilità:
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Ma il tipo di i
non sarà const (ovvero, il compilatore utilizzerà std::vector<char>::iterator
come tipo di i
).
In questo caso, potresti anche usare solo un typedef
(non limitato a C ++ 11, e molto utile da usare comunque):
typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
contatore
Ovviamente puoi usare un tipo intero per registrare la tua posizione nel for
loop:
for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
Se hai intenzione di farlo, è meglio usare i tipi di membri del contenitore, se disponibili e appropriati. std::vector
ha un tipo di membro chiamato size_type
per questo lavoro: è il tipo restituito dal size
metodo.
// Path typedef'd to std::vector<char>
for( Path::size_type i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
Perché non utilizzarlo solo sulla iterator
soluzione? Per casi semplici potresti anche, ma il punto è che la iterator
classe è un oggetto progettato per fare questo lavoro per oggetti più complicati in cui questa soluzione non sarà ideale.
basato su intervallo per loop (C ++ 11)
Vedi la soluzione di Jefffrey . In C ++ 11 (e versioni successive) è possibile utilizzare il nuovo for
ciclo basato su intervallo , che assomiglia a questo:
for (auto i: path)
std::cout << i << ' ';
Poiché path
è un vettore di elementi (esplicitamente std::vector<char>
), l'oggetto i
è di tipo dell'articolo del vettore (cioè, esplicitamente, è di tipo char
). L'oggetto i
ha un valore che è una copia dell'elemento effettivo path
nell'oggetto. Pertanto, tutte le modifiche a i
nel ciclo non vengono conservate in path
sé. Inoltre, se si desidera applicare il fatto che non si desidera poter modificare il valore copiato i
nel ciclo, è possibile forzare il tipo di i
essere in const char
questo modo:
for (const auto i: path)
std::cout << i << ' ';
Se desideri modificare gli elementi in path
, puoi utilizzare un riferimento:
for (auto& i: path)
std::cout << i << ' ';
e anche se non vuoi modificare path
, se la copia di oggetti è costosa dovresti usare un riferimento const invece di copiare per valore:
for (const auto& i: path)
std::cout << i << ' ';
std :: copia
Vedi la risposta di Giosuè . È possibile utilizzare l'algoritmo STL std::copy
per copiare i contenuti vettoriali sul flusso di output. Questa è una soluzione elegante se ti senti a tuo agio (e inoltre, è molto utile, non solo in questo caso di stampa del contenuto di un vettore).
std :: for_each
Vedi la soluzione di Max . L'utilizzo std::for_each
è eccessivo per questo semplice scenario, ma è una soluzione molto utile se si desidera fare qualcosa di più della semplice stampa su schermo: l'utilizzo std::for_each
consente di eseguire qualsiasi operazione (ragionevole) sui contenuti vettoriali.
sovraccarico ostream :: operatore <<
Vedi la risposta di Chris , questo è più un complemento delle altre risposte poiché dovrai ancora implementare una delle soluzioni sopra nel sovraccarico. Nel suo esempio ha usato un contatore in un for
ciclo. Ad esempio, ecco come è possibile utilizzare rapidamente la soluzione di 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'uso di una qualsiasi delle altre soluzioni dovrebbe essere semplice.
conclusione
Qualsiasi delle soluzioni presentate qui funzionerà. Dipende da te e dal codice su cui si è il "migliore". Qualcosa di più dettagliato di questo è probabilmente meglio lasciare per un'altra domanda in cui i pro / contro possono essere adeguatamente valutati; ma come sempre le preferenze dell'utente avranno sempre un ruolo: nessuna delle soluzioni presentate è sbagliata, ma alcune appariranno più belle per ogni singolo programmatore.
appendice
Questa è una soluzione estesa di una precedente che ho pubblicato. Dal momento che quel post ha continuato a ricevere attenzione, ho deciso di ampliarlo e fare riferimento alle altre eccellenti soluzioni che sono state pubblicate qui. Il mio post originale aveva un'osservazione che ha detto che se fossi intenzione sulla modifica vettore all'interno di un for
ciclo, allora ci sono due metodi forniti da std::vector
ad elementi di accesso: std::vector::operator[]
che non fa il controllo dei limiti, e std::vector::at
che fa eseguire il controllo dei limiti. In altre parole, at
verrà lanciato se si tenta di accedere a un elemento esterno al vettore e operator[]
non lo farebbe. Ho solo aggiunto questo commento, in origine, per citare qualcosa che potrebbe essere utile sapere se qualcuno lo avesse già fatto. E non vedo alcuna differenza ora. Da qui questo addendum.