読者です 読者をやめる 読者になる 読者になる

関数オブジェクト

関数オブジェクトは、括弧付で呼び出すことで、関数の様に振る舞うことができるオブジェクト・・・。
といっても、コンストラクタも括弧付で呼び出す場合があるので、何が違うのかとおもうだろう・・・。
コンストラクタは生成時の最初の1回だが、関数オブジェクトは何度も呼ぶことができる・・・。
関数オブジェクトは、C言語の関数ポインタと同様に、コールバック関数として使われることが多い・・・。
関数ポインタでべき乗の数列、関数オブジェクトでべき乗和の数列(べき級数)を表してみる・・・。

関数オブジェクトの正体は括弧"()"演算子オーバーロード・・・。
これで引数をもらうこともできる・・・。
class_powはべき乗和を計算するのでtotal_に和を格納しておかないといけない・・・。
関数ポインタはこのような状態を保持する手段が基本的に無い(static変数とかはあるけど)ので、こういうところは関数オブジェクトのメリット・・・。

for_each_expはvectorの先頭から末尾まで関数ポインタfuncが指す関数に要素を渡し結果を返してもらう・・・。
func_expはその関数ポインタに渡す関数・・・。

for_each_powは関数オブジェクト版、class_powのオブジェクトを第3引数にもらう・・・。

関数ポインタの場合は、powの戻り値をそのまま返してる・・・。

関数オブジェクトの場合、powでxのi乗を求めて、それをtotal_に格納、そしてそれを返す・・・。

for_each_expは、もらった関数ポインタfuncにitor参照先の数値と何番目かを渡している・・・。
0番目なら0乗、1番目なら1乗、2番目なら2乗というように中で計算されて、結果をもとのitor参照先に返す・・・。

for_each_powは関数オブジェクトobjにitor参照先の数値と何番目かを渡している・・・。
こちらは和なので、0番目は0乗、1番目は1乗( + 0乗)、2番目は2乗( + 1乗 + 0乗)という感じで結果が返ってくる・・・。

vec1に2を5個追加して、for_each_expを呼ぶと、i番目の要素が2のi乗した値になる・・・。

vec2に2を5個追加して、for_each_powを呼ぶと、i番目の要素が2の0乗から2のi乗までの和になる・・・。

$ vi function_object.cpp
$ g++ function_object.cpp -o function_object
$ ./function_object
*itor = 1
*itor = 2
*itor = 4
*itor = 8
*itor = 16

*itor = 1
*itor = 3
*itor = 7
*itor = 15
*itor = 31
$

上は2の0乗から、2の4乗まで・・・。
下は2の0乗までの和から、2の4乗までの和・・・。
このように、オブジェクトなので状態を保持でき、和のような計算に使える・・・。

Sample/cpp/function_object/function_object/src/function_object at master · bg1bgst333/Sample · GitHub