你可以从http://boost.sourceforge.net/index.htm ;下载boost库,我们需要的是boost的type_traits一组头文件。
下载完 boost库之后,并设置好包含路径,让我们开始修改我们的Call函数,对指针和引用做出适当的改变。
有了boost库之后,测试一个模板参数T是指针还是引用再也简单不过了:
#include <boost/type_traits.hpp>
using namespace boost;
template <typename RT, typename P1>
int Call(RT (*Func) (P1), lua_State *L, int idx)
{
is_pointer<P1>::value || is_reference<P1>::value;
}
现在我们已经能够得到一个bool值,如果这个值为真,我们并不试图从lua栈中获取这样的参数,而是首先将它交给调用函数处理,然后再作为返回值交给lua,并且返回的时候,是返回这个指针所指内容的拷贝。如果为假,我们仅仅将它作为参数交给调用函数。
为了能够做到编译期的静态分派,我们使用函数的重载机制,首先,我们需要定义一个bool到类型的映射,以区别参数的类型:
template <bool B>
struct bool2type
{
enum { value = B };
};
为了清晰起见,我们对两种形式做一个typedef:
typedef bool2type<true> ResultType;
typedef bool2type<false> NormalType;
对于一个参数来说,如果它的标志是ResultType,那么它将作为结果交给lua,如果是第二种形式,那么它仅仅交给被调函数。
现在我们要为一个参数的Call函数提供两个版本的_Call函数,以区分其指针参数调用和正常调用:
template <typename RT, typename P1>
int _Call(RT (*Func)(P1), ResultType, lua_State *L, int idx)
{
}
template <typename RT, typename P1>
int _Call(RT (*Func)(P1), NormalType, lua_State *L, int idx)
{
}
现在我们在Call函数中可以直接交给_Call来处理:
template <typenaem RT, typename P1>
int Call(RT(*Func)(P1), lua_State *L, int idx)
{
return _Call(*Func,
bool2type<is_pointer<P1>::value
|| is_reference<P1>::value>(), L, idx);
}