0

オブジェクトの範囲で特定のものを計算するためのファンクターのセットがあります。基本的に、各ファンクターは次を実装しoperator()ます。

template <typename Iterator1,
          typename Iterator2> double operator()( Iterator1 it1,
                                                 Iterator2 it2 ) const
{
  return( 0.0 );
}

これで、さまざまなファンクターで作成できるオブジェクトのセットができました。クリエーター関数をテンプレート化することでこれを解決しました:

template <class Functor> Foo createFoo( ... // some parameters for foo objects
                                        Functor f = Functor() )
{
  // calculate stuff for "foo" using functor "f"
}

ファンクターの選択をプログラムのユーザーに委譲したいので、ファンクター ファクトリを作成することにしました。Fooファンクターのわかりやすい名前を指定して、上記のようにすべてのオブジェクトの作成に使用できるように、適切なファンクターを作成したいと考えています。

ただし、ここで行き詰まります。テンプレート化されたファンクターを返すファクトリを作成することはできません。これは、作成したい正確なタイプのファンクターをコーディングせずにこの関数を呼び出すことができないためです。

operator()いくつかの基本クラスの仮想関数、つまり を作成することを考えましたFunctorBaseが、仮想関数の呼び出しに関連するパフォーマンスのオーバーヘッドは望ましくありません。最初にテンプレートを使用することを選択した理由は、前述のオーバーヘッドを回避することでした。

私はここで行き詰まっており、いくつかのコメントをいただければ幸いです。

編集

私がやろうとしていること (無効なコード):

DistanceFunctor f = createFunctor( "Bar" ); // Create a functor from a client-supplied string

Foo createFoo( ..., // parameters for foo
               f );

コメントでは、仮想関数の使用も提案されました。ただし、コンパイラは関数テンプレートを仮想化できないため、上記の現在のファンクター設計は仮想関数では機能しません。ファンクター クラスを調整して、2 つの Iterator 型をテンプレート パラメーターとして使用することは可能ですが、非常に扱いにくいものです。

編集

ファンクタは、FLANN で使用されるものと同様に機能します。例については、git リポジトリを参照してください。これらのファンクターを別の方法で指定する方法がわかりません。

4

1 に答える 1