利用c++0x新特性来实现一个lua binder, 这是个超级雏形,基本上实现了从函数参数的拆卸和重新组装。
从xLB_caller压入两个实参(模拟lua_State可以给我们提供实参)
template<class R, class...A> struct xLB_caller {};
template<class R, class...A>
struct xLB_caller<R (*)(A...)> {
typedef R (*function_t)(A...);
function_t __final;
xLB_caller(function_t _final) : __final(_final) {
__values.push(999);
__values.push(333);
}
std::queue<int> __values;
template<typename T>void loadarg(T& __v) {
__v = __values.front();
__values.pop();
}
};
然后利用variadic template,逐个从xLB_caller中提供实参,等所有实参拆卸完毕后,再逐个组装回去,最终执行对函数的调用。效果差不多就是这样子。
int x(int a, int b) {
int r = a-b;
std::cout << "x(" << a << "," << b << ") -> " << std::dec << r << std::endl;
return r;
}
int main() {
xLB_wf<decltype(&x)> awx(&x);
awx();
return 0;
}
输出结果
C:\loonlib\bakefiles\function>f2
x(999,333) -> 666
result : 666
完整的代码
#include <iostream>
#include <functional>
#include <queue>
using namespace std;
using namespace std::placeholders;
/*============================================================================
*
============================================================================*/
template<class R, class...A> struct xLB_caller {};
template<class R, class...A>
struct xLB_caller<R (*)(A...)> {
using function_t = R (*)(A...);
using return_t = R;
function_t __final;
xLB_caller(function_t _final) : __final(_final) {
__values.push(999);
__values.push(333);
__values.push(111);
}
std::queue<int> __values;
template<class T>void loadarg(T& __v) {
__v = __values.front();
__values.pop();
}
};
template<int N, class caller_t, class...A> struct xLB_getparam{};
template<class caller_t, class...A>
struct xLB_getparam<0, caller_t, A...> {
using return_t = typename caller_t::return_t;
caller_t* __caller;
xLB_getparam(caller_t* _caller) : __caller(_caller) {}
void operator()(){ /* N==0 no more param for getting */ };
template<class...VA> return_t part(VA..._args) {
return __caller->__final(_args...);
}
};
template<int N, class caller_t, class T, class ...A>
struct xLB_getparam<N, caller_t, T, A...> {
using next_t = xLB_getparam<N-1, caller_t, A...>;
using return_t = typename caller_t::return_t;
caller_t* __caller;
next_t __next;
T __arg;
xLB_getparam(caller_t* _caller) : __caller(_caller), __next(_caller) {}
void operator()() {
__caller->loadarg(__arg);
__next();
}
template<class...VA> return_t part(VA...__args) {
return __next.part(__args..., __arg);
}
return_t part(){ return __next.part(__arg); }
};
template<class R> struct xLB_wf{};
template<class R, class ...A>
struct xLB_wf<R (*)(A...) > {
using function_t = R(*)(A...);
using caller_t = xLB_caller<R (*)(A...)>;
using geter_t = xLB_getparam<sizeof...(A), caller_t, A...>;
caller_t __caller;
geter_t __g;
xLB_wf(function_t _realfunc) : __caller(_realfunc), __g(&__caller) {}
R operator()() { __g(); return __g.part(); }
};
template<class R, class S, class ...A>
struct xLB_wf<R (S::*)(A...) > {
};
template<class X>
auto xLB_bind(X f) -> xLB_wf<decltype(f)>{
return xLB_wf<decltype(f)>(f);
}
/*============================================================================
*
============================================================================*/
int x(int a, int b, int c) {
int r = a-b-c;
std::cout << "x(" << a << "," << b << "," << c << ") -> " << std::dec << r << std::endl;
return r;
}
int main() {
//xLB_wf<decltype(&x)> awx(&x);
auto awx = xLB_bind(&x);
std::cout << "awx() -> " << awx() << std::endl;
return 0;
}