関数オブジェクトは、STL アルゴリズムと一緒によく使用されます。関数オブジェクトは、これらのアルゴリズムのおかげで生まれましたか? C++ で関数オブジェクトを使用するのはいつですか? その利点は何ですか?
7 に答える
関数オブジェクト (ファンクター) は通常、関数ポインターの代わりに使用されます。関数ポインターには、通常、コンパイラーがそれらを生のポインターとして渡すという問題があり、コンパイラーが後でコードをインライン化するのが難しくなります。また、パラメータを与えるのも簡単です。
関数オブジェクトは、STL に対する強力な抽象化レイヤーを可能にするように設計されており、その点で優れています。
boost::bind
ただし、代わりに関数を使用して STL アルゴリズムにバインドすることを好みます。通常は (オブジェクトに状態がある場合ではありませんが)、より洗練されたソリューションと思われます。
std::for_each( callback.begin(), callback.end(),
boost::bind(&Callback::call(),_1)
);
また、別の今後の代替案は C++0x のラムダです (Wikipedia から恥知らずに盗まれた例):
std::vector<int> someList;
int total = 0;
std::for_each(someList.begin(), someList.end(), [&total](int x) {
total += x;
});
std::cout << total;
クロージャーにより、状態を持たないというバインドの制限がないことに注意してください。
この記事では、関数オブジェクトについて深く掘り下げて説明し、関数オブジェクトによってコードをより強力かつクリーンにする方法について説明します。
関数をオブジェクトとしてカプセル化するという考えは、Lisp と Smalltalk にさかのぼります。functor の C++ のアイデアは、1991 年の Jim Coplien の著書Advanced C++ Programming Styles and Idiomsの章でした。STLはこの慣用句を使用し、それをさらに普及させました。
なぜ彼らが生まれたのかはわかりません - おそらく単に可能だったからです!
ファンクターはいつ使用しますか?ファンクターは、通常ループに入れるコードをクラスの operator() に移動するだけであると考えてください。それらは while ループで関数を呼び出すこととそれほど違いはありません...ただし、それらを使用することを除いてコンパイラがコードをインライン化できるようにし、代わりに、何らかの状態で構築した事前構築済みのオブジェクトを渡すこともできます。後者の点により、それらは非常に強力になります。
ソート アルゴリズムを CRT の qsort 呼び出しと比較します。彼らは同じことをしますが、やり方がまったく異なります。