実際、これらは2つの関連する質問です。
次の形式の範囲ベースのfor
ループ用のC++ 11に新しい構文があることを知っています。
//v is some container
for (auto &i: v){
// Do something with i
}
最初の質問:このループのどの反復であるかをどのように推測できますか? (位置jでベクトルを値jで埋めたいとしましょう)。
2番目の質問:フォームのループを記述する他の方法があるかどうかを知りたい
for (int i=0; i<100; i++) { ... }
この書き方は少し面倒だと思うし、これを頻繁にやるので、もっと簡潔な構文が欲しいです。線に沿って何か:
for(i in [0..99]){ ... }
素晴らしいことだ。
どちらの質問についても、追加のライブラリを使用する必要はありません。
最初の答え:そうではありません。単純な目的のために単純な構造を使用しました。より複雑なニーズがある場合は、より複雑なものが必要になります。
2番目の答え:連続した整数値を生成するイテレータ型と、それらの範囲を提供する「コンテナ」型を作成できます。あなたが自分でそれをする正当な理由がない限り、Boostには そのようなこと があります:
#include <boost/range/irange.hpp>
for (int i : boost::irange(0,100)) {
// i goes from 0 to 99 inclusive
}
最初の質問に対する答えは非常に簡単です。反復カウントが必要な場合は、反復カウントを抽象化する構文構造を使用しないでください。範囲ベースのループではなく、通常のfor
ループを使用してください。
2番目の質問については、標準ライブラリには現在何も存在しないと思いますが、 boost::irange
そのため:
for (int i : boost::irange(0, 100))
2番目の質問- Boost が重すぎる場合は、常にこのライブラリを使用できます。
for(auto i : range(10, 15)) { cout << i << '\n'; }
は_10 11 12 13 14
_を出力します
for(auto i : range(20, 30, 2)) { cout << i << '\n'; }
は_20 22 24 26 28
_を出力します
倍精度やその他の数値型もサポートされています。
他のPython反復ツールがあり、ヘッダーのみです。
Boost.Rangeを使用すると、これらの両方を実行できます。 http://boost.org/libs/range
boost::adaptors::indexed
:要素の値とインデックスboost::irange
:整数範囲簡潔にするために(そして、少しスパイスを入れるために、boost::irange
は既に単独でデモンストレーションされています)、これらの機能が連携して動作することを示すサンプルコードを次に示します。
// boost::adaptors::indexed
// http://www.boost.org/doc/libs/master/libs/range/doc/html/range/reference/adaptors/reference/indexed.html
#include <boost/range/adaptor/indexed.hpp>
// boost::irange
// http://www.boost.org/doc/libs/master/libs/range/doc/html/range/reference/ranges/irange.html
#include <boost/range/irange.hpp>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> input{11, 22, 33, 44, 55};
std::cout << "boost::adaptors::indexed" << '\n';
for (const auto & element : input | boost::adaptors::indexed())
{
std::cout << "Value = " << element.value()
<< " Index = " << element.index()
<< '\n';
}
endl(std::cout);
std::cout << "boost::irange" << '\n';
for (const auto & element : boost::irange(0, 5) | boost::adaptors::indexed(100))
{
std::cout << "Value = " << element.value()
<< " Index = " << element.index()
<< '\n';
}
return 0;
}
サンプル出力:
boost::adaptors::indexed
Value = 11 Index = 0
Value = 22 Index = 1
Value = 33 Index = 2
Value = 44 Index = 3
Value = 55 Index = 4
boost::irange
Value = 0 Index = 100
Value = 1 Index = 101
Value = 2 Index = 102
Value = 3 Index = 103
Value = 4 Index = 104
2番目の質問:
別の方法もありますが、私は使用も推奨もしませんにします。ただし、テストをすばやく設定するには、次のように記述できます。
ライブラリを使用したくなく、範囲の上限を指定するだけでよい場合は、次のように記述できます。
for (auto i:vector<bool>(10)) {
cout << "x";
}
これにより、初期化されていない値を持つサイズ10のブールベクトルが作成されます。 i
を使用してこれらの初期化された値をループします((not使用i
)10回 "x"を出力します。
v
がベクトル(または任意のstd
連続コンテナ)の場合、
for(auto& x : v ) {
size_t i = &x-v.data();
x = i;
}
i番目のエントリに値i
を設定します。
カウントする出力反復子は、かなり簡単に記述できます。 Boost には1つがあり、irange
と呼ばれる生成しやすい範囲があります。
コンテナのインデックスの抽出は比較的簡単です。 indexes
という関数を作成しました。この関数は、コンテナーまたは整数の範囲を取り、問題の範囲でランダムな出力反復子を生成します。
それはあなたに与えます:
for (size_t i : indexes(v) ) {
v[i] = i;
}
Boostには、おそらく同等のコンテナからインデックスへの範囲関数があります。
両方が必要で、作業をしたくない場合は、ジッパーを作成できます。
for( auto z : Zip( v, indexes(v) ) ) {
auto& x = std::get<0>(z);
size_t i = std::get<1>(z);
x = i;
}
ここで、Zip
は2つ以上の反復可能な範囲(またはコンテナー)を取り、要素へのiterator_traits<It>::reference
sのタプルの範囲ビューを生成します。
Boost Zipイテレータは次のとおりです: http://www.boost.org/doc/libs/1_41_0/libs/iterator/doc/Zip_iterator.html - -おそらく、上記のZip
関数のような構文を処理するBoost Zip範囲があります。
2番目の質問では、最新のVisual Studioバージョンを使用している場合は、「if」と入力してから Tab、 Tab、そして Tab 初期値、ステップアップなどを入力します。