2

一般的なタイプに作用するファンクターを作成したいとします。例えば

template<typename Ape>
class functor1
{
   void operator()(Ape& m)
   {
      // Do something to m
   }
};

これは私にとって物事を行うための標準的な方法です。ただし、別の方法もあります。

class functor2
{
   template<typename Ape>
   void operator()(Ape& m)
   {
      // Do something to m
   }
};

2番目のアプローチの利点は、テンプレートのタイプを明示的に指定する必要がないことです。

int main()
{
   std::vector<chimpanzee> chimps(100);
   for_each(chimps.begin(), chimps.end(), functor1<chimpanzee>()); // Explicity state the type
   for_each(chimps.begin(), chimps.end(), functor2()); // Less typing. Will it work?
}

2番目のバージョンは機能しますか?それとも私は何かが足りないのですか?それが機能する場合、最初のアプローチに何か利点はありますか?

4

3 に答える 3

3

明らかな違いは、最初のケースでは型を明示的に指定し、2 番目のケースでは実際の呼び出しのコンテキストで型を推測するのはコンパイラであることです。ただし、特定の例では、実際の違いはまったくない場合があります。

  1. クラスに複数のメンバー関数がある場合、最初のバリアントはそれらすべてに対して同じテンプレート パラメーターを「修正」しますが、2 番目のバリアントではパラメーターは各メンバー関数に対して個別に推定されます。

    単一のメンバー関数が複数のコンテキストから呼び出される場合も同様です。各コンテキストは、2 番目のバリアントで独自のテンプレート引数推定を実行します。

    あなたの意図に応じて、それは良いこともそうでないこともあります。

  2. 関数が引数を値 (またはconst参照) で受け入れる場合、最初のバリアントでは、コンテナーに格納されているものとは異なる型を引数に指定できます。たとえば、 のファンクターを作成し、longそれを s のコンテナーに適用することができますint。これは、2 番目のバリアントでは不可能です。

    たとえば、chimpanzeeクラスが から派生したポリモーフィックである場合animal、 を使用しfunctor1<animal>てそのようなコンテナを反復処理できます。2 番目のバリアントでは、テンプレート パラメーターは aschimpanzeeではなく として推測されますanimal

  3. クラスにデータ メンバーがある場合、2 番目のバリアントは、同じファンクター オブジェクトが使用されている場合、メンバー関数のすべての特殊化が同じデータを共有することを確認します。最初のバリアントでは、各特殊化は異なるクラスであり、独自のデータを取得します。

于 2012-07-11T14:25:17.437 に答える
1

これはスコープのようなものです。infunctor1では、クラス内のすべてが型Ape(メンバー宣言、パラメーターおよび戻り型の型、特性など)を使用できますが、infunctor2ではApe、の範囲内の何かのみを意味しますoperator()。要するに:

  • 定義の時間:
    • functor1Apeいつ作成されるかを知る必要があります
    • functor2Ape呼び出されるまで知る必要はありません
  • タイプの範囲:
    • のすべてfunctor1がについて知っていApeます。
    • operator()でのみfunctor2知っていApeます。
  • インスタンスの汎用性:
    • functor1インスタンスは、単一のタイプの。でのみ機能しますApe
    • functor2インスタンスは、任意のタイプで機能しますApe
于 2012-07-11T14:34:43.043 に答える
1

状態のないファンクタの場合、これは同じである必要があります。ファンクターに同じタイプの別のオブジェクト/参照/ポインターを保存する必要があることがよくありますが、その場合、2番目のオプションは機能しません。make_<foo>ファンクターがコンストラクターのパラメーターを必要とする場合は、タイプを推測するような自由な関数を作成して、make_pairタイピングを減らすことができることに注意してください。

于 2012-07-11T14:22:06.927 に答える