c++boost.gif (8819 bytes)HomeLibrariesPeopleFAQMore

Miscellaneous Notes

Boost.Function vs. Function Pointers

Boost.Function には関数ポインタに比べていくつかの利点がある。

  • Boost.Function は、任意の互換性がある関数オブジェクトを格納できる (関数ポインタは全く同じシグネチャを持つ関数しか受け付けない) 。

  • Boost.Function は、引数の束縛などの関数オブジェクトを作り出すライブラリと共用できる。

  • Boost.Function を使えば、空の関数オブジェクトが呼び出された時に、その事が分かるような動作をする。

そしてもちろん、関数ポインタにも Boost.Function に比べていくつかの利点がある。

  • 関数ポインタはサイズが小さい (関数ポインタはポインタ 1 つ、 Boost.Function はポインタ 3 つ) 。

  • 関数ポインタは高速だ (Boost.Function は関数ポインタを通した呼び出しを 2 回する可能性がある) 。

  • 関数ポインタは C のライブラリと下位互換性がある。

  • エラーメッセージが読みやすい。

Performance

Function object wrapper size

関数オブジェクトのラッパのサイズは 2 つの関数ポインタと、 1 つの関数ポインタまたはデータのポインタ (の大きい方) のサイズになる。一般的な 32 ビットプラットフォームでは、 1 つのラッパ当たり 12 バイトになる。さらに、対象となる関数オブジェクトがヒープに割り当てられる。

Copying efficiency

関数オブジェクトのラッパのコピーによって、格納された関数オブジェクトのコピーのためにメモリ割り当てが発生する。デフォルトのアロケータを、もっと早いカスタムアロケータで置換する事もできる。また、関数オブジェクトのラッパが、対象となる関数オブジェクトの「参照」だけを格納するように指定できる (ref を使用) 。これは関数オブジェクトのコピーが酷く高価な場合に有効だ。

Invocation efficiency

適切なインライン化を行うコンパイラならば、関数オブジェクトの呼び出しによって、関数ポインタを通した呼び出しが 1 回行われる。非メンバ関数ポインタの呼び出しならば、それ加えてもう 1 回関数ポインタの呼び出しが行われる (コンパイラがとても強力な関数をまたいだ分析を行うならば別だが) 。

Combatting virtual function "bloat"

多くのコンパイラでは、仮想関数の使用によって「コードの膨張」が起きがちである。クラスが仮想関数を持つ場合、オブジェクトの型を分類する補助関数を作る必要が有る。私達の経験では、多くの boost::function オブジェクトが使われると、この補助関数が実行可能ファイルのサイズを大きく膨張させる。

Boost.Function では、仮想関数の代わりに非メンバ関数を使った、代わりの等価なアプローチをとっている。 Boost.Function オブジェクトが関数オブジェクトを呼び出すためには、本質的に 2 つのポインタを持つ必要がある。所有する関数オブジェクトへの void ポインタと、関数オブジェクトの「呼び出し役」への void ポインタ (関数ポインタが代入される) だ。 Boost.Function が提供する、引数と戻り値の変換は、この呼び出し役が実行する。第 3 のポインタは「管理者」と呼ばれる非メンバ関数を指す。これは関数オブジェクトのコピーと破棄を扱う。この方法はタイプセーフだ。なぜなら、関数オブジェクトを実際に扱う関数である呼び出し役と管理者は、関数オブジェクトの型を知らされてインスタンス化されるので、入ってくる void ポインタ (関数オブジェクトへのポインタ) を、正しい型に安全にキャストできるからだ。

Acknowledgements

たくさんの人がこのライブラリの作成に参加した。 William Kempf 、 Jesse Jones 、 Karl Nelson は、ライブラリのインタフェースと守備範囲を、他のライブラリとは独立したものにする上で大きな助けになってくれた。 John Maddock は公式なレビューをやってくれた。他にもたくさんの人がレビューをして、インタフェース、実装、ドキュメントについて優れたコメントを寄せてくれた。Peter Dimov は私達に関数宣言子ベースの文法を教えてくれた。

Last revised: February 19, 2003 at 22:46:09 GMTCopyright © 2001-2003 Douglas Gregor