関数オブジェクトは、括弧付で呼び出すことで、関数の様に振る舞うことができるオブジェクト・・・。
といっても、コンストラクタも括弧付で呼び出す場合があるので、何が違うのかとおもうだろう・・・。
コンストラクタは生成時の最初の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乗までの和・・・。
このように、オブジェクトなので状態を保持でき、和のような計算に使える・・・。