純粋にあなたの質問に答えるために、あなたはイテレータを使うことができます:
std::vector<char> path;
// ...
for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
forループでベクターの内容を変更する場合は、iterator
ではなくを使用してくださいconst_iterator
。
しかし、これについて言えることはもっとたくさんあります。使用できる答えだけが必要な場合は、ここで停止できます。それ以外の場合は読み続けてください。
自動(C ++ 11)/ typedef
これは別のソリューションではなく、上記のiterator
ソリューションの補足です。C ++ 11標準(またはそれ以降)を使用している場合は、auto
キーワードを使用して読みやすくすることができます。
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
ただし、のタイプはi
非定数になります(つまり、コンパイラはstd::vector<char>::iterator
のタイプとして使用されますi
)。
この場合、typedef
(C ++ 11に限定されず、とにかく非常に便利です)を使用することもできます。
typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
カウンター
もちろん、整数型を使用してfor
ループ内の位置を記録できます。
for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
これを行う場合は、コンテナーのメンバータイプが使用可能で適切な場合は、それを使用することをお勧めします。このジョブに対してstd::vector
呼び出されるメンバータイプsize_type
があります。これは、size
メソッドによって返されるタイプです。
// Path typedef'd to std::vector<char>
for( Path::size_type i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
なぜこれをiterator
ソリューションで使用しないのですか?単純な場合も同様ですが、重要なのは、iterator
クラスは、このソリューションが理想的ではない、より複雑なオブジェクトに対してこの仕事をするように設計されたオブジェクトであることです。
範囲ベースのforループ(C ++ 11)
Jefffreyのソリューションを参照してください。C ++ 11以降for
では、次のような新しい範囲ベースのループを使用できます。
for (auto i: path)
std::cout << i << ' ';
以来path
アイテム(明示のベクトルであるstd::vector<char>
)、オブジェクトがi
ベクトルの項目のタイプである(すなわち、明示的に、そのタイプのものですchar
)。オブジェクトにi
は、path
オブジェクト内の実際のアイテムのコピーである値があります。したがって、i
ループ内のすべての変更は、path
それ自体では保持されません。さらに、コピーした値を変更できないようにしたいという事実を強制したい場合i
ループ内での場合は、タイプを次のi
ように強制できますconst char
。
for (const auto i: path)
std::cout << i << ' ';
でアイテムを変更したい場合 path
場合は、参照を使用できます。
for (auto& i: path)
std::cout << i << ' ';
変更したくない場合でも path
、オブジェクトのコピーに負荷がかかる場合は、値によるコピーの代わりにconst参照を使用する必要があります。
for (const auto& i: path)
std::cout << i << ' ';
std :: copy
ジョシュアの答えを見てください。STLアルゴリズムを使用できますstd::copy
を、ベクトルの内容を出力ストリームにコピーます。これは、慣れていればエレガントなソリューションです(しかも、ベクトルの内容を印刷する場合だけでなく、非常に便利です)。
std :: for_each
Maxのソリューションを参照してください。std::for_each
この単純なシナリオでは、使用はやり過ぎですが、画面に出力するだけではない場合は、非常に便利なソリューションです。使用std::for_each
すると、ベクターコンテンツに対して任意の(賢明な)操作を実行できます。
オーバーロードostream :: operator <<
クリスの回答を参照してください。これは、オーバーロードで上記のソリューションの1つを実装する必要があるため、他の回答をさらに補完するものです。彼の例では、for
ループでカウンターを使用しました。たとえば、これは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;
}
他のソリューションの使用は簡単です。
結論
ここで紹介するソリューションはどれも機能します。それはあなたと1つが「最高」であるコード次第です。これよりも詳細なことは、おそらく賛否両論を適切に評価できる別の質問に任せるのが最善です。しかし、いつものように、ユーザーの好みが常に役割を果たすでしょう:提示された解決策のどれも間違っていませんが、いくつかは個々のコーダーに見栄えがします。
補遺
これは、以前に投稿したソリューションの拡張ソリューションです。その投稿が注目を集め続けているので、私はそれを拡張して、ここに投稿された他の優れたソリューションを参照することにしました。私のオリジナルのポストは、あなたがあればそれを言及した発言だったし、内部のあなたのベクトルの変更に意図for
そこが提供する2つの方法ですループをstd::vector
:アクセス要素にstd::vector::operator[]
境界チェックしません、とstd::vector::at
した境界チェックを行います。言い換えれば、at
ベクトルの外側の要素にアクセスしようとしてもアクセスしない場合にスローされますoperator[]
。元々、私がこのコメントを追加したのは、誰かがまだしなかった場合に知っておくと役立つかもしれないことを説明するためです。そして、私は今、違いはありません。したがって、この補遺。