2009-03-07 5 views
0

私はC++テンプレートを使用して、関数ファンクタを渡して関数の動作を変更しています。それはうまく動作します。私が渡すファンクタは、ストレージのないステートレスクラスであり、古典ファンクタの方法で()演算子をオーバーロードします。Functorクラスがコンストラクタで作業をしています

template <typename Operation> int foo(int a) 
{ 
int b=Operation()(a); 
/* use b here, etc */ 
} 

これは頻繁に実行され、うまく動作し、よくテンプレート化された6人または7人のテンプレートが作成されています。

しかし、私はコードの優雅さと効率についても心配しています。ファンクタはステートレスなので、Operation()コンストラクタはフリーであり、ファンクタの評価はインライン関数と同じくらい効率的ですが、すべてのC++プログラマのように、私はいつも疑問を持っています。

もう1つの質問は、代替ファンクタアプローチを使用できるかどうかです。()演算子をオーバーライドしませんが、コンストラクタ内のすべてを副作用として実行します。 何かのように:

struct Operation { 
    Operation(int a, int &b) { b=a*a; } 
}; 
template <typename Operation> int foo(int a) 
{ 
    int b; 
    Operation(a,b); 
    /* use b here, etc */ 
} 

私は、誰もがファンクタの「作品」としてコンストラクタを使用し見たことがないが、それが動作するはずのように思えます。利点はありますか?不利な点はありますか?私は奇妙な二重のかっこ "演算子()(a)"の除去が好きですが、それはまさに美的かもしれません。

答えて

2

何か不利な点がありますか?

  • Ctorsは、任意の有用な値を返さない - 連鎖コール(例えばFOO(バー())で使用することはできません
  • 彼らは投げることができるビューの
  • デザインポイントを - 。。ctorsがあります
+0

誰が投げられないのですか? –

+0

@Mykola Golubyev:Dtors - 少なくとも、あなたは投げるべきではありません。 – dirkgently

1
  1. コンパイラは、実際に運用の空のコンストラクタインライン
  2. コンストラクタですべてを行うことの欠点は、あなたには、いくつかのとファンクタを作成することができないということである(同様の状況で、少なくともGCCを使用すると、最適化をオフにする場合を除き、ありません)このように内部状態 - 例えば。述語を満たす要素の数を数えるファンクタ。また、実際のオブジェクトのメソッドをファンクタとして使用すると、後で実行するためにそのインスタンスを保存することができます。これは、コンストラクタのアプローチではできないものです。
1

実演されたコードからは、VCとGCCの両方で完全に最適化されたコードが得られます。ただし、ファンクタをパラメータとして使用する方が効率的です。あなたはより多くの柔軟性を得る方法同一の性能特性を有する。

0

STLコンテナで動作するファンクタを定義することをお勧めします。つまり、operator()を実装する必要があります。

これは、アルゴリズムが非常に汎用的であることを可能にします(関数、ファンクタ、stl-bind、boost :: function、boost :: bindを渡すことができます)。 、boost :: lambda、...)これは普通誰が望むものです。

この方法で、あなただけのインスタンスを作成し、それを渡し、テンプレートパラメータとして数子のタイプを指定する必要はありません。

my_algorithm(foo, bar, MyOperation()) 
0

別では、コンストラクタを実装する際に任意のポイントがあるようではありませんクラス。
あなたがしていることは、カプセル化を破ってクラスを悪用するように設定することだけです。

コンストラクタは、オブジェクトをクラスによって定義された良好な状態に初期化することになっています。他のオブジェクトがクラスを初期化できるようにしています。このテンプレートクラスがクラスを正しく初期化する方法を知っていることを保証するものは何ですか?クラスのユーザーは、意図していない方法でオブジェクトの内部状態を混乱させる可能性のあるオブジェクトを提供できます。

クラスは自己完結型であり、良好な状態に初期化する必要があります。あなたがしているように見えるのは、テンプレートで遊ぶことだけです。

関連する問題