2

これらの 質問により、各マクロの Boost と Qt の目的に興味を持ちました。

私は Qt を使用しており、マクロは常に私のニーズに対して十分に機能していましたが、そのパフォーマンスを広範囲にテストしたことはありません。Boost の製品を使用したことはありません。

私が知りたいのは、Qt と Boost over が提供する代替手段をいつ使用するのが良いかということstd::for_eachです。

注:質問をより客観的にするために、文言は元のものから変更されています。

4

3 に答える 3

5

の目的と機能は、マクロや とstd::for_eachは大きく異なります。BOOST_FOREACHQ_FOREACH

std::for_each何よりもまず、関数呼び出しです。アルゴリズムです。これを呼び出して、反復子のペアを提供します。イテレータ範囲の各メンバーで、問題のイテレータからフェッチされた値で指定された関数を呼び出します。

の目的はstd::for_each、概念的に言えば、既存のより具体的なアルゴリズムと一致させることです。count、 などのアルゴリズムcopyでは、すべての要素に対して任意のコードを単純に実行するアルゴリズムを持つことは理にかなっています。

BOOST_FOREACHQ_FOREACHは同等の構成要素 (まとめて と呼びますFOREACH) ですが、とは動作が異なりstd::for_eachます。

FOREACH何よりもまず、for ループです。それほど違いはないように聞こえるかもしれませんが、考えてみてください。内からcontinueとを呼び出すことはできません。で簡単にエミュレートできます(ただし、これは、呼び出しを発行した関数から戻ることができないことも意味します)。しかし、やめたいと思ったら、ループから抜け出す方法はありません。同様に、ループから抜け出すことはできません。どちらの場合でもできる最善の方法は、例外をスローすることです。これは、フロー制御に例外を使用しています (つまり、良い考えではありません)。breakstd::for_eachcontinuereturnstd::for_eachstd::for_eachgotofor_each

を使用する場合std::for_each、呼び出し可能な関数を提供する必要があります。これは、関数ポインターまたは関数オブジェクトである可能性があります。そのため、コードは多少非ローカライズされています。これは、各反復で行っていることが複雑な複数行の関数である場合には問題ありません。ただし、各反復のロジックが非常に単純な場合、コードの可読性は少し低下します。

FOREACHコードのローカル ブロックを実行します。コードはそこにあります。各反復で何が起こっているかを確認するために関数を追跡する必要はありません。

また、関数を呼び出すということは、その関数を作成する必要があることを意味します。状態を追跡する必要がある場合は、ファンクターが必要になり、より多くのコードを記述する必要があります。

C++11 では、ラムダ関数がより魅力的になりますstd::for_each これにより、コードの局所性の問題が解消されます。ソース コードはすぐそこにあります。また、ラムダは何かをキャプチャできるため、通常のforループとほぼ同じように機能します。まあ、break機能がないことを除けば、それは通常避けられます.

もちろん、C++11 では、範囲ベースのループを(とともに) 効果的に廃止しています。ただし、C++11 にはさまざまなレベルの適合性があるため、ラムダはあるが範囲ベースではない環境がいくつかあります。FOREACHforfor

何を使うべきかはあなた次第です。FOREACHBoost や Qt を既に使用している場合は、ご自由にどうぞ。しかし、私は突然これらを使い始めるつもりはありませんFOREACH。個人的には、std::for_eachコードの局所性の問題により、ラムダなども使用していない限り使用しません。forループを使用するだけです。

于 2012-05-10T21:31:51.923 に答える
1

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);
  }

使用法:最も読みやすく、不要なコードの重複を回避できると思うもの。

パフォーマンス:これらはすべてマクロまたはテンプレート関数のいずれかであり、コンパイラーに完全に表示されます。違いは、デバッグビルドにのみ存在する必要があります。

于 2012-05-10T21:20:56.903 に答える
1

std::for_eachはC++標準の一部であり、(少なくとも)1998年から使用されています。したがって、(それほどではない)最新のC ++は非準拠であるため、が提供されていない場合は機能しなくなりますfor_each。私が日常的に使用しているすべてのコンパイラはそれをサポートしています。

あなたが言及する両方のライブラリは、C++言語自体の外部にあります。 for_each準拠コンパイラに存在することが保証されているのは1つだけです。

長所と短所については、私はあなたに決定を任せます。選択肢があれば、そうでないものよりも標準で保証されているものを選びます。

于 2012-05-09T22:19:15.523 に答える