C/C++ / Python風のデコレータを書いてみたい ── 関数ポインタ

前回までは、 Pythonのデコレータについて、説明させていただきました。

公式や他サイト様の劣化焼き直しになっているようで、申し訳なく思います。

今回は、「C++ でデコレータをやってみた」というネタです。 前回までの投稿は、この説明のためでもありました。

元々、デコレータはデザインパターンなので、クラス階層で実装することができます。 しかし、ここではPython風に関数を基本に実装します。

C++11は使わず、C++03の制限内でやります。

関数ポインタ

デコレータは"関数を受けとり、関数を返す"関数を作れば OK です。 しかし、C++の関数は第一級ではないので、関数を受けとることも関数を返すことも一手間必要になります。 関数ポインタや関数オブジェクトという奴です。 まずは関数オブジェクトは後回しに、関数ポインタだけでいきます。

とりあえず、関数を受けとり、そのまま実行する方法を示します。


// main.cc
#include <stdio.h>


// /////////////////////////////////////////////////////////
// ==================================================
typedef int (*decorated_func_t)(int);
// ==================================================
int decorator(decorated_func_t a_Func, int a_Int) {
  printf("KOOL!!! ");
  return a_Func(a_Int) * 2;
}
// ==================================================
int hoge(int a_Int) {
  return a_Int * 2;
}
// ==================================================
int main(int argc, const char* argv[]) {
  printf("%d\n", decorator(&hoge, 10));
  return 0;
}

先ず、typedef int (*decorated_func_t)(int);で、関数ポインタの型を宣言します。 これで、decorated_func_tが関数ポインタを受け取れる型になります。 ただし、『戻り値がintで引数がint1つの関数』のみです。

main関数内の&hogeが、関数のポインタを取得している部分です。 decoratatの第一引数がdecorated_func_tなので、これを受け取ることができます。

関数ポインタはCでも使えるので、上記コードはC言語のみで記述しているのと同じです。


gcc --ansi main.cc -o main
./main 
KOOL!!! 40

実行すると、decoratorから渡した10がhogeで2倍、decoratorで2倍と増えて、最終的に40が出力されています。

decorator(&hoge, 10) が返すのは関数ではなく、実行した値であることに注意が必要です。

──続きます。

目録

  1. C/C++ / Python風のデコレータを書いてみたい ── 関数ポインタ
  2. C/C++ / Python風のデコレータを書いてみたい ── 関数オブジェクト
  3. C/C++ / Python風のデコレータを書いてみたい ── テンプレート
  4. C/C++ / Python風のデコレータを書いてみたい ── Buffered Loop

0 件のコメント:

コメントを投稿