これらの 質問により、各マクロの Boost と Qt の目的に興味を持ちました。
私は Qt を使用しており、マクロは常に私のニーズに対して十分に機能していましたが、そのパフォーマンスを広範囲にテストしたことはありません。Boost の製品を使用したことはありません。
私が知りたいのは、Qt と Boost over が提供する代替手段をいつ使用するのが良いかということstd::for_each
です。
注:質問をより客観的にするために、文言は元のものから変更されています。
の目的と機能は、マクロや とstd::for_each
は大きく異なります。BOOST_FOREACH
Q_FOREACH
std::for_each
何よりもまず、関数呼び出しです。アルゴリズムです。これを呼び出して、反復子のペアを提供します。イテレータ範囲の各メンバーで、問題のイテレータからフェッチされた値で指定された関数を呼び出します。
の目的はstd::for_each
、概念的に言えば、既存のより具体的なアルゴリズムと一致させることです。count
、 などのアルゴリズムcopy
では、すべての要素に対して任意のコードを単純に実行するアルゴリズムを持つことは理にかなっています。
BOOST_FOREACH
とQ_FOREACH
は同等の構成要素 (まとめて と呼びますFOREACH
) ですが、とは動作が異なりstd::for_each
ます。
FOREACH
何よりもまず、for ループです。それほど違いはないように聞こえるかもしれませんが、考えてみてください。内からcontinue
とを呼び出すことはできません。で簡単にエミュレートできます(ただし、これは、呼び出しを発行した関数から戻ることができないことも意味します)。しかし、やめたいと思ったら、ループから抜け出す方法はありません。同様に、ループから抜け出すことはできません。どちらの場合でもできる最善の方法は、例外をスローすることです。これは、フロー制御に例外を使用しています (つまり、良い考えではありません)。break
std::for_each
continue
return
std::for_each
std::for_each
goto
for_each
を使用する場合std::for_each
、呼び出し可能な関数を提供する必要があります。これは、関数ポインターまたは関数オブジェクトである可能性があります。そのため、コードは多少非ローカライズされています。これは、各反復で行っていることが複雑な複数行の関数である場合には問題ありません。ただし、各反復のロジックが非常に単純な場合、コードの可読性は少し低下します。
FOREACH
コードのローカル ブロックを実行します。コードはそこにあります。各反復で何が起こっているかを確認するために関数を追跡する必要はありません。
また、関数を呼び出すということは、その関数を作成する必要があることを意味します。状態を追跡する必要がある場合は、ファンクターが必要になり、より多くのコードを記述する必要があります。
C++11 では、ラムダ関数がより魅力的になりますstd::for_each
。これにより、コードの局所性の問題が解消されます。ソース コードはすぐそこにあります。また、ラムダは何かをキャプチャできるため、通常のfor
ループとほぼ同じように機能します。まあ、break
機能がないことを除けば、それは通常避けられます.
もちろん、C++11 では、範囲ベースのループを(とともに) 効果的に廃止しています。ただし、C++11 にはさまざまなレベルの適合性があるため、ラムダはあるが範囲ベースではない環境がいくつかあります。FOREACH
for
for
何を使うべきかはあなた次第です。FOREACH
Boost や Qt を既に使用している場合は、ご自由にどうぞ。しかし、私は突然これらを使い始めるつもりはありませんFOREACH
。個人的には、std::for_each
コードの局所性の問題により、ラムダなども使用していない限り使用しません。for
ループを使用するだけです。
std :: for_eachを実行するには、ファンクター、ラムダ、または関数ポインターが必要です。これを使用すると、コード内の複数の場所で同じメソッドをループする場合に、多くの定型文を回避できます。
void hello(int i){
printf("World %d \n",i);
}
std::vector<int> vals;
vals.push_back(1);
vals.push_back(2);
std::for_each(vals.begin(),vals.end(),hello);
BOOST_FOREACHとQ_FOREACHは、c ++イテレーターの定型文を非表示にするために使用され、通常のforステートメントを置き換えてループ本体をループします。
for(vector<int>::iterator iter = vals.begin();iter != vals.end();++iter)
{
hello(*iter);
}
Q_FOREACH(int val, vals){
hello(val);
}
使用法:最も読みやすく、不要なコードの重複を回避できると思うもの。
パフォーマンス:これらはすべてマクロまたはテンプレート関数のいずれかであり、コンパイラーに完全に表示されます。違いは、デバッグビルドにのみ存在する必要があります。
std::for_each
はC++標準の一部であり、(少なくとも)1998年から使用されています。したがって、(それほどではない)最新のC ++は非準拠であるため、が提供されていない場合は機能しなくなりますfor_each
。私が日常的に使用しているすべてのコンパイラはそれをサポートしています。
あなたが言及する両方のライブラリは、C++言語自体の外部にあります。 for_each
準拠コンパイラに存在することが保証されているのは1つだけです。
長所と短所については、私はあなたに決定を任せます。選択肢があれば、そうでないものよりも標準で保証されているものを選びます。