オブジェクトの範囲で特定のものを計算するためのファンクターのセットがあります。基本的に、各ファンクターは次を実装し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 リポジトリを参照してください。これらのファンクターを別の方法で指定する方法がわかりません。