オブジェクト指向プログラミングにおいて、関数のように振る舞うことができるオブジェクトのことです。
通常、単なる変数であれば、関数のように呼び出して使うことはできません。反対に、単なる関数であれば、それ自体が値を記憶しておくことはできません(同じ関数が繰り返し呼び出されるときに、以前の情報を共有できない)。関数オブジェクトは変数と関数の両方の性質を併せ持ち、値(状態)を持ちながら、関数のように処理の内容を定義しておくことができます。
関数オブジェクトは、関数ポインタやラムダ式のように、関数を引数として受け取ったり、コールバック関数として利用したりすることが多いです。
状態を持たせられることは関数オブジェクトの利点です。たとえば関数ポインタを使う方法では、それ自体は状態を持てないため、状態を管理するための工夫が必要になり、コードが複雑になってしまうことがあります。関数オブジェクトであれば、動作を現在の状態に基づいて変化させることも簡潔に行えます。
C++ の関数オブジェクトはクラス型のオブジェクトとして実現し、operator() をオーバーロードすることで、関数として呼び出すことができます。
次のプログラムでは、operator() をオーバーロードした CountUpクラスを定義し、count_up という変数(オブジェクト)を作っています。operator() がオーバーロードされていることにより、count_up() という呼び出しが可能になり、変数でありながら関数のように呼び出すことができています。
#include <iostream>
struct CountUp {
    int operator()() {
        return value++;
    }
    int value {};
};
int main()
{
    CountUp count_up {0};
    for (int i = 0; i < 5; ++i) {
        std::cout << count_up() << "\n";
    }
}実行結果:
0
1
2
3
4
C++ の関数オブジェクトについての解説は、新C++編「シャッフルと乱数」にあります。
標準ライブラリにおいては、STLアルゴリズムに、探索や比較のための条件を伝えるときなどで関数オブジェクトを使う機会があります(状態が不要なら関数でも構わない)。
C++11 で導入されたラムダ式を使うと、関数オブジェクトを簡潔に記述できます。
C++ のラムダ式についての解説は、新C++編「関数ポインタとラムダ式」にあります。
関数オブジェクトは通常の関数よりもインライン化されやすい(しやすい)傾向があり、パフォーマンスが向上することがあります。
Programming Place Plus のトップページへ
| はてなブックマーク に保存 | Facebook でシェア | X で ポスト/フォロー | 
| LINE で送る | noteで書く | 
	
	 | 
| 管理者情報 | プライバシーポリシー |