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

C#みたいなFunc、ActionをC++でも使いたい

という夢企画。ソースはすごく汚いですがとりあえずFuncだけサンプル。
説明は後でがんまります。

#include<stdio.h>
#include<string.h>

#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	

// テストクラス
class A {
	char name[30];
public:
	A(char n[]) { strcpy(name, n); }
	void f() { printf("%s : call f()\n", name); }
	int g() { return 10; }
	int h(int a) { return a; }
	int i(int a, int b) { return a + b; }
};

int main()
{
	A a("aaa");
	A *pa = &a;
	Func0<A, int> f0(a, &A::g);
	printf("%d\n", f0());
	Func1<A, int, int> f1(a, &A::h);
	printf("%d\n", f1(3));
	Func2<A, int, int, int> f2(a, &A::i);
	printf("%d\n", f2(3, 4));

	Func0<A*, int> fp0(pa, &A::g);
	printf("%d\n", fp0()); 
	Func1<A*, int, int> fp1(pa, &A::h);
	printf("%d\n", fp1(5));
	Func2<A*, int, int, int> fp2(pa, &A::i);
	printf("%d\n", fp2(3, 4));


	getchar();
}

きっとint以外もできるはず。
ポインタとか混じってもできるはず。
Actionもすぐ作れるはず。
・・・後で書きます。