続・C#みたいなFunc、ActionをC++でも使いたい
というわけでついさっきC#みたいなFunc、ActionをC++でも使いたい - プログラム備忘録書きました。
それの続きです
とりあえず作った物を貼り付けて行きます。
- Func.h
#ifndef __FUNC_H__ #define __FUNC_H__ // Function Delegate class #define FuncDelegate(arg_num, template_types, args_types, func_arg, use_var) \ template <class Cls, template_types class Ret> \ class Func##arg_num \ {\ typedef Ret (Cls::*pFunc)(func_arg);\ pFunc func;\ Cls c;\ Ret f(func_arg) {\ return (c.* func)(use_var);\ }\ public:\ Func##arg_num(Cls c, pFunc func) : c(c), func(func) {}\ Ret operator()(func_arg){return f(use_var);}\ };\ \ template <class Cls, template_types class Ret> \ class Func##arg_num<Cls*, args_types Ret> \ {\ typedef Ret (Cls::*pFunc)(func_arg);\ pFunc func;\ Cls *c;\ Ret f(func_arg) {\ return (c->* func)(use_var);\ }\ public:\ Func##arg_num(Cls *c, pFunc func) : c(c), func(func) {}\ Ret operator()(func_arg){return f(use_var);}\ };\ \ // Func0の定義 #define TEMPLATE_TYPES #define ARGS_TYPES #define FUNC_ARG #define USE_VAR FuncDelegate(0, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR // Func1の定義 #define TEMPLATE_TYPES class A1, #define ARGS_TYPES A1, #define FUNC_ARG A1 a1 #define USE_VAR a1 FuncDelegate(1, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR // Func2の定義 #define TEMPLATE_TYPES class A1, class A2, #define ARGS_TYPES A1, A2, #define FUNC_ARG A1 a1, A2 a2 #define USE_VAR a1, a2 FuncDelegate(2, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR // Func3の定義 #define TEMPLATE_TYPES class A1, class A2, class A3, #define ARGS_TYPES A1, A2, A3, #define FUNC_ARG A1 a1, A2 a2, A3 a3 #define USE_VAR a1, a2, a3 FuncDelegate(3, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR // Func4の定義 #define TEMPLATE_TYPES class A1, class A2, class A3, class A4, #define ARGS_TYPES A1, A2, A3, A4, #define FUNC_ARG A1 a1, A2 a2, A3 a3, A4 a4 #define USE_VAR a1, a2, a3, a4 FuncDelegate(4, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR #endif
- Action.h
#ifndef __ACTION_H__ #define __ACTION_H__ #define ActionDelegate(arg_num, template_types, args_types, func_arg, use_var) \ template <class Cls template_types> \ class Action##arg_num \ {\ typedef void (Cls::*pFunc)(func_arg);\ pFunc func;\ Cls c;\ void f(func_arg) {\ (c.* func)(use_var);\ }\ public:\ Action##arg_num(Cls c, pFunc func) : c(c), func(func) {}\ void operator()(func_arg){f(use_var);}\ };\ \ template <class Cls template_types> \ class Action##arg_num<Cls* args_types> \ {\ typedef void (Cls::*pFunc)(func_arg);\ pFunc func;\ Cls *c;\ void f(func_arg) {\ (c->* func)(use_var);\ }\ public:\ Action##arg_num(Cls *c, pFunc func) : c(c), func(func) {}\ void operator()(func_arg){f(use_var);}\ };\ \ // Action0の定義 #define TEMPLATE_TYPES #define ARGS_TYPES #define FUNC_ARG #define USE_VAR ActionDelegate(0, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR // Action1の定義 #define TEMPLATE_TYPES ,class A1 #define ARGS_TYPES ,A1 #define FUNC_ARG A1 a1 #define USE_VAR a1 ActionDelegate(1, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR // Action2の定義 #define TEMPLATE_TYPES , class A1, class A2 #define ARGS_TYPES , A1, A2 #define FUNC_ARG A1 a1, A2 a2 #define USE_VAR a1, a2 ActionDelegate(2, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR // Action3の定義 #define TEMPLATE_TYPES , class A1, class A2, class A3 #define ARGS_TYPES , A1, A2, A3 #define FUNC_ARG A1 a1, A2 a2, A3 a3 #define USE_VAR a1, a2, a3 ActionDelegate(3, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR // Action4の定義 #define TEMPLATE_TYPES , class A1, class A2, class A3, class A4 #define ARGS_TYPES , A1, A2, A3, A4 #define FUNC_ARG A1 a1, A2 a2, A3 a3, A4 a4 #define USE_VAR a1, a2, a3, a4 ActionDelegate(4, TEMPLATE_TYPES, ARGS_TYPES, FUNC_ARG, USE_VAR) #undef TEMPLATE_TYPES #undef ARGS_TYPES #undef FUNC_ARG #undef USE_VAR #endif
クラスの関数しか試してません。
static関数やグローバル関数には試してません。
多分クラスの関数にのみ稼動すると思われます。
それぞれ
- Func##引数の数<[呼び出す関数のクラスの型], [関数の引数の型...], [戻り値の型]>
- Action##引数の数<[呼び出す関数のクラスの型], [関数の引数の型...]>
となります。
使用例は
#include <stdio.h> #include "Func.h" #include "Action.h" class A { public: inline double pow(int n) { return n * n; } inline void route(char from[], char to[]) { printf("%s から %s までのルート\n", from, to);} }; int main() { A a; // 引数1戻り値ありならFunc1 Func1<A, int, double> f1(a, &A::pow); printf("%lf\n", f1(5)); // 引数2戻り値なしならAction2 Action2<A, char[], char[]> f2(a, &A::route); f2("札幌", "東京"); }
実行結果は
25.000000 札幌 から 東京 までのルート
となります。
ほかの関数も対応させたいところ。
いい案があったら教えてくださいm(_ _)m