网站建设投,成都网站制作,wordpress系统语言设置,比较出名的网站建设公司在c中#xff0c;函数参数类型和返回值类型通常是一个比较明确的信息#xff0c;好像确实无需在这个上面费周折。然而#xff0c;硬编码数据类型会让代码复用性下降#xff0c;如果能够通过某种方式自动获取函数参数和返回值类型#xff0c;对于代码的可复用性#xff0c…在c中函数参数类型和返回值类型通常是一个比较明确的信息好像确实无需在这个上面费周折。然而硬编码数据类型会让代码复用性下降如果能够通过某种方式自动获取函数参数和返回值类型对于代码的可复用性可读性和整洁性都有较大的提升。最近阅读GoogleTest的源码(v1.8.1)发现它采用了模板方法实现了这一点
// googletest/googlemock/include/gmock/internal
/gmock-generated-internal-utils.h...
template typename F
struct Function;template typename R
struct FunctionR() {typedef R Result;...
};template typename R, typename A1
struct FunctionR(A1): FunctionR() {typedef A1 Argument1;...
};template typename R, typename A1, typename A2
struct FunctionR(A1, A2): FunctionR(A1) {typedef A2 Argument2;...
};template typename R, typename A1, typename A2, typename A3
struct FunctionR(A1, A2, A3): FunctionR(A1, A2) {typedef A3 Argument3;...
};...
上面的代码gmock在使用的时候是配合宏实现不同类型函数的统一。在实际开发中我们可以借助decltypeauto以及函数指针的方式来对函数的返回值和参数类型进行统一拆分只需对上述代码进行稍微调整即可
template typename T
struct Function;//以下以__stdcall 调用类型为例如果函数调用类型是 __cdcel, 则需要特化新的模板组
template typename R
struct FunctionR __stdcall() {typedef R RESULT;
};template typename R, typename A1
struct FunctionR __stdcall(A1) :FunctionR __stdcall()
{typedef A1 ARG1;
};template typename R, typename A1, typename A2
struct FunctionR __stdcall(A1,A2) :FunctionR __stdcall(A1)
{typedef A2 ARG2;
};template typename R, typename A1, typename A2,typename A3
struct FunctionR __stdcall(A1, A2,A3) :FunctionR __stdcall(A1,A2)
{typedef A3 ARG3;
};//如果是函数指针类型可以用以下模板特化组
template typename R
struct FunctionR(__stdcall*)() {typedef R RESULT;
};template typename R, typename A1
struct FunctionR(__stdcall*)(A1) :FunctionR(__stdcall*)()
{typedef A1 ARG1;
};template typename R, typename A1, typename A2
struct FunctionR(__stdcall*)(A1,A2) :FunctionR(__stdcall*)(A1)
{typedef A2 ARG2;
};template typename R, typename A1, typename A2,typename A3
struct FunctionR(__stdcall*)(A1,A2,A3) :FunctionR(__stdcall*)(A1,A2)
{typedef A3 ARG3;
};// 如果有更多参数可在此处扩展
测试代码
int __stdcall STD_CALL_FUNC_WITH_ONE_PARAM(int b)
{int nn 0;return nn;
}int main(int argc, char* argv[], char* env[])
{//typedef int (__stdcall *Func)(int);using Func decltype(STD_CALL_FUNC_WITH_ONE_PARAM);Func bvn STD_CALL_FUNC_WITH_ONE_PARAM;Functiondecltype(bvn)::RESULT result1;Functiondecltype(bvn)::ARG1 arg1;auto funcAutoPtr STD_CALL_FUNC_WITH_ONE_PARAM;Functiondecltype(funcAutoPtr)::RESULT result2;Functiondecltype(funcAutoPtr)::ARG1 arg2;Functiondecltype(STD_CALL_FUNC_WITH_ONE_PARAM)::RESULT result3;Functiondecltype(STD_CALL_FUNC_WITH_ONE_PARAM)::ARG1 arg3;return 0;
}