分享

C++调用lua函数的通用call,参数数目任意、参数类型任意

 quasiceo 2014-01-13

C++调用lua函数的通用call,参数数目任意、参数类型任意  

2012-10-23 13:07:53|  分类: C++ |  标签:lua  bind  c++temlate  trait  参数   |字号 订阅

我们只要用过一些成熟的lua对c++的绑定,例如SLB、luabind或者其他,就会想:为什么它们会这么神奇,可以在C++实现参数数目任意、参数类型任意的函数。现在我们来探讨它们的本质,这里只讨论它们的最初原型,当然现实的bind会非常复杂。

例如:实现调用lua函数的通用方法;

call("add",112, 2323.33); // 调用lua 的add方法,参数是一个整数和一个double

call("print","helloworld");// 调用lua 的 print 方法,参数是一个C-style 字符串"helloworld"

call("print",222222);// 调用lua 的 print 方法,参数是一个整数

将我们后面讨论的方法稍稍修改下,也可以实现上面的神奇调用。

核心思想

对每种不同的参数类型 ,分别调用不同的处理函数Do()


//原型要首先声明

template<typename T>

struct Trait

{

       static void Do(T t);  

};

//利用偏特化

template<>

struct Trait<int>

{

       static void Do(int t)

       {

              std::cout<<" Type int "<<t ;

       }

}; 

template<>

struct Trait<float>

{

       static void Do(float t)

       {

              std::cout<<"Type float "<<t ;

       }

};

 

template<>

struct Trait<double>

{

       static void Do(double t)

       {

              std::cout<<" Type double "<<t ;

       }

};

 

//char const *类型 无法从这里实例化,WHY

template<>

struct Trait<char*>

{

       static void Do(chart)

       {

              std::cout<<" Type char* "<<t ;

       } 

};

 

//奇怪的是 char *类型 无法从这里实例化 WHY

template<>

struct Trait<char const*>

{

       static void Do(char constt)

       {

              std::cout<<" Type char const* "<<t ;

       } 

};

 

template<>

struct Trait<std::string>

{

       static void Do(std::string t)

       {

              std::cout<<" Type std::string "<<t ;

       }

};

 


 关键的地方

template<typename T1typename T2>

void Call(T1 t1T2 t2)//自动推导

{   

      // 在函数内部,T1、T2已经被推导出来了,因此后面可以直接T1、T2来实例化其他的模版  

    //衔接前后    

       Trait<T1>::Do(t1);

       Trait<T2>::Do(t2);  

};


template<typename T1,typename T2,typename T3 ,typename T4>

void Call(T1 t1,T2 t2,T3 t3 ,T4 t4)

{  

       Trait<T1>::Do(t1);  

       Trait<T2>::Do(t2);  

       Trait<T3>::Do(t3);  

       Trait<T4>::Do(t4);      

};


实现的效果:

Call(11,1111);

Call("hello","world");

Call("HelloGuys");

Call(11, 22.2, 232.3f, std::string("fdsaf"));

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多