pandaxcl的专栏--我的网站开站啦:http://www.autodev.net

熊春雷的专栏

panda ID:pandaxcl
77669次访问,排名1133好友0人,关注者1
pandaxcl的文章
原创 61 篇
翻译 0 篇
转载 0 篇
评论 151 篇
pandaxcl的公告

博客文档资源下载在本人的网站下载!!!

我也优先在我的网站论坛上面回答问题

在研究C++自动化编程好久之后,发现C++自动化编程在国内还是一个空白。所谓的C++自动化编程,简单点说就是采用了C++的高级模板技术配合产生式编程技法实现了C++代码的自我配置,自动维护代码之间的种种一致性问题。关于这个问题的讨论,将会在我的网站上面进行细致的讨论。如果有问题,欢迎来我的网站提问哦。看看下面的我的网站的链接。

EMail:pandaxcl@163.com

QQ:56637059

我的网站: http://www.autodev.net

最近评论
huxi043715:博主,在很强阿。你的文章也很容易懂。
wangwei200508:呵呵,谢了
您的这里指到自己硬盘了
<a href="file:///D:/work/lex_yacc/chapter01/lexyacc.rar.png" target="_top">这里</a>
imath:老大我引用了你的 这系列文章,嘿嘿
dlr0987:abc* = ab (c+|e) =ab|abc|abcc.....

pandaxcl:这里要注意那个return i
前置和后置都是为了实现增一的效果;)
特意实现前置和后置都是相同的功能的;)
文章分类
收藏
    相册
    友情连接
    小熊猫
    我的另外一个博客
    我的网站-自动化编程社区
    我的论坛-自动化编程社区论坛
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 自动化C++程序设计---基础篇_分析C++重载函数(1)--分析函数参数的数量收藏

    新一篇: 自动化C++程序设计---基础篇_分析C++重载函数(2)--分析函数参数的种类

    书名: 《自动化C++程序设计》
    作者: 熊春雷
    网站: http://www.autodev.net
    Blog: http://blog.csdn.net/pandaxcl
    EMail: pandaxcl@163.com
    昵称: pandaxcl,开心
    QQ: 56637059
    MSN: pandaxcl@163.com
    版本: 0.01 于2007/09/25
    目标: 所有C++爱好者
    版权: 本文的版权归熊春雷所有
    代码库: autocxx(在论坛下载

    Warning

    1. 本文由熊春雷所写,绝对保证原创,在此特别严肃声明。本人简介:熊春 雷,男,1980年出生于湖北钟祥;七岁随父迁往宜昌开始学生生涯,小学和初中在 湖北宜昌樟村坪镇职工子弟学校就读;1996年考上宜昌县高中,开始三年的高中生 活;1999-2003就读于湖北大学物理系;2003-2006就读于武汉大学物理系。现就职 于盛大网络:)

    2. 绝对不能容忍他人说本文为他所写以及其他的侵权行为。一旦发现,一定 尽本人最大的能力以法律的形式严追到底,决不妥协。

    3. 引用本文,要保证本文的完整性,不可以删除此处的声明,并且务必注明出处。

    Tip

    1. 本文编写的所有代码可以用于任何用途(包括商业用途)。

    2. 用于商业用途的需要在最后发布的软件中声明借鉴了本文的思想。具体事 宜可以协商解决,(代码决不收取任何费用)。

    3. 其他事项可以和我联系,包括技术讨论等等:)或者直接登陆网站论坛: http://www.autodev.net

    Note

    1. 本文受到了《C++设计新思维》和《产生式编程》两本书的影响,同时也查阅了大 量的资料,从Loki库和Boost库中也吸收了不少营养,特此感谢之。

    2. 本文由于处于原创阶段,难免会出现各种各样的错误。代码出现错误的可能性非常 小(本来想说为零的),因为文档和代码是严格同步的,这是由VST文本的include 所保证的,代码都是测试成功之后才发布的。

    3. 本文所编写的代码,经过了VC2005编译器和g++编译器的测试,并且都通过了。

    4. 本文还没有彻底完成,算是一个初级版本,未来还将继续完善。暂时发布出来是为 了预知读者群有多少,读者越多,我的成就感越强,写作的时候也会更有动力:)

    5. 本文还会继续完善,欢迎各位读者的批评指正,也接受各种各样的建议,在权衡之 后以决定是否加入本书。

    6. 本书还没有最终完成,还会不断的进行完善,更新之后的内容将会发表于我的 网站我的博客。所以还需要读者多多关心本文的进展:)

    Contents

    分析函数参数的数量

    目的

    在分析C++代码的时候,特别是分析C++函数(仿函数)的时候,若是能够分析出在一个名 字空间(类域)里面的指定函数名称的函数的参数的数量将会是非常有用的:)这一章就 对这个问题进行详细的分析。

    原理实现

    实现的基本原理如下:

    1. 假定一个比较大的函数参数数量,例如5个

    2. 从0开始递增的探测所有的函数参数数量

    3. 利用函数参数能够实现隐式转型,将any类型转换成指定的类型

    下面是名字空间内的函数参数数量分析的实例:

     namespace A// 名字空间域  {      kind<9> on(...);// 这个函数是测试所必须的      int on(n<0>);// 一个参数      int on(n<0>,n<1>,n<2>);// 三个参数      int on(n<0>,n<1>,n<2>,n<3>);// 四个参数  }// namespace A   // 下面的静态断言的“==”表示不存在这个函数,而“!=”表示存在这个函数  static_assert<sizeof(kind<9>)==sizeof(A::on())>();  static_assert<sizeof(kind<9>)!=sizeof(A::on(any()))>();  static_assert<sizeof(kind<9>)==sizeof(A::on(any(),any()))>();  static_assert<sizeof(kind<9>)!=sizeof(A::on(any(),any(),any()))>();  static_assert<sizeof(kind<9>)!=sizeof(A::on(any(),any(),any(),any()))>();  static_assert<sizeof(kind<9>)==sizeof(A::on(any(),any(),any(),any(),any()))>();  

    下面是类域内的函数参数数量分析的实例:

     struct A// 类域  {      kind<9> on(...);// 这个函数是测试所必须的      int on(n<0>);// 一个参数      int on(n<0>,n<1>,n<2>);// 三个参数      int on(n<0>,n<1>,n<2>,n<3>);// 四个参数  };   // 下面的静态断言的“==”表示不存在这个函数,而“!=”表示存在这个函数  static_assert<sizeof(kind<9>)==sizeof(A().on())>();  static_assert<sizeof(kind<9>)!=sizeof(A().on(any()))>();  static_assert<sizeof(kind<9>)==sizeof(A().on(any(),any()))>();  static_assert<sizeof(kind<9>)!=sizeof(A().on(any(),any(),any()))>();  static_assert<sizeof(kind<9>)!=sizeof(A().on(any(),any(),any(),any()))>();  static_assert<sizeof(kind<9>)==sizeof(A().on(any(),any(),any(),any(),any()))>();  

    从上面的代码可以看出:

    1. any可以用来实现匹配任意类型,类似于正则表达式中的通配符“.”

    2. 函数重载和自动(隐式)转型

    起到了极其重要的作用!

    到此为止,已经成功的给出了函数参数数量探测的原理实现。在上面的代码中,大量出现 的static_assert可以看做是一个静态循环过程,现在的问题就是如何将这里的这些静态断 言的功能的原理实现 自动化 。关于这个问题的解决办法就要采用前面的章节中介绍 的代码产生功能了:)

    自动化实现

    从前面的原理实现可以看出,实际上就是一个静态循环过程,把这个静态循环过程用C++静 态代码封装一下就可以了。在封装之前需要知道结果是什么:

    封装的结果就是函数参数数量的 数值类型列表(mkps<n<1>,n<3>,n<4> >) !前面的测 试用例里面有1个参数、3个参数和4个参数的函数,所以所得的结果就是n<1>,n<3>,n<4> 组成的类型串。

     struct A// 类域  {      kind<9> on(...);// 这个函数是测试所必须的      int on(n<0>);// 一个参数      int on(n<0>,n<1>,n<2>);// 三个参数      int on(n<0>,n<1>,n<2>,n<3>);// 四个参数  };  // 从0到5判断sizeof(T的函数调用)!=sizeof(kind<9>)是否成立,成立则保存到结果中  template<class T,class i>struct Filter;  // 下面的代码类似于一个大型的静态switch结构:)case条件是n<i>  template<class T>struct Filter<T,n<0> >// 是否是没有参数的函数类型  {      enum{i = sizeof(T().on())!=sizeof(kind<9>)};      typedef n<i> type;  };  template<class T>struct Filter<T,n<1> >// 是否是1个参数的函数类型  {      enum{i = sizeof(T().on(any()))!=sizeof(kind<9>)};      typedef n<i> type;  };  template<class T>struct Filter<T,n<2> >// 是否是2个参数的函数类型  {      enum{i = sizeof(T().on(any(),any()))!=sizeof(kind<9>)};      typedef n<i> type;  };  template<class T>struct Filter<T,n<3> >// 是否是3个参数的函数类型  {      enum{i = sizeof(T().on(any(),any(),any()))!=sizeof(kind<9>)};      typedef n<i> type;  };  template<class T>struct Filter<T,n<4> >// 是否是4个参数的函数类型  {      enum{i = sizeof(T().on(any(),any(),any(),any()))!=sizeof(kind<9>)};      typedef n<i> type;  };  template<class T>struct Filter<T,n<5> >// 是否是5个参数的函数类型  {      enum{i = sizeof(T().on(any(),any(),any(),any(),any()))!=sizeof(kind<9>)};      typedef n<i> type;  };  

    下面就是上面的初步自动化的测试用例:

     typedef filter<range<0,5+1>::type,A,Filter>::type RESULT;//[0,6)  static_assert_same<mkps<n<1>,n<3>,n<4> >::type,RESULT>();  

    上面的代码就已经自动化实现了分析函数参数的数量的功能了,只不过函数的名称被定死 了(on)!

    从上面的代码还可以看出自动化的实现需要:

    1. 给出一个比较大的函数参数数量(前面的函数参数数量最多是4个,所以给5就可以了)

    2. 针对于每一个函数参数数量,分别提供一个静态测量函数Filter

    3. 上面的被测试函数名称被限制成了on,这是不必要的,但是似乎只能通过宏的方式实现

    通常来说,给出一个比较大的参数数量就可以了,一般情况下,给定十个参数就够用了:

     // 创建在分析函数参数数量和类型的模板中使用的函数模板  #define AUTOCXX_DEFINE_FUNCTION(Func,Class)                                    \  template<class Type,class Kind,class ArgPS>struct Class;                       \  template<class Type,class Kind>                                                \      struct Class<Type,Kind,nil                                                 \      >                                                                          \  {                                                                              \      enum{i=(sizeof(Type().Func())!=sizeof(Kind))};                             \      typedef n<i> type;                                                         \  };                                                                             \  template<class Type,class Kind,class A0>                                       \      struct Class<Type,Kind,p<A0>                                               \      >                                                                          \  {                                                                              \      enum{i=(sizeof(Type().Func(A0()))!=sizeof(Kind))};                         \      typedef n<i> type;                                                         \  };                                                                             \                                                                                 \  template<class Type,class Kind,class A0,class A1>                              \      struct Class<Type,Kind,p<A0,p<A1>                                          \      > >                                                                        \  {                                                                              \      enum{i=(sizeof(Type().Func(A0(),A1()))!=sizeof(Kind))};                    \      typedef n<i> type;                                                         \  };                                                                             \                                                                                 \  template<class Type,class Kind,class A0,class A1,class A2>                     \      struct Class<Type,Kind,p<A0,p<A1,p<A2>                                     \      > > >                                                                      \  {                                                                              \      enum{i=(sizeof(Type().Func(A0(),A1(),A2()))!=sizeof(Kind))};               \      typedef n<i> type;                                                         \  };                                                                             \                                                                                 \  template<class Type,class Kind,class A0,class A1,class A2,class A3>            \      struct Class<Type,Kind,p<A0,p<A1,p<A2,p<A3>                                \      > > > >                                                                    \  {                                                                              \      enum{i=(sizeof(Type().Func(A0(),A1(),A2(),A3()))!=sizeof(Kind))};          \      typedef n<i> type;                                                         \  };                                                                             \                                                                                 \  template<class Type,class Kind,class A0,class A1,class A2,class A3,class A4>   \      struct Class<Type,Kind,p<A0,p<A1,p<A2,p<A3,p<A4>                           \      > > > > >                                                                  \  {                                                                              \      enum{i=(sizeof(Type().Func(A0(),A1(),A2(),A3(),A4()))!=sizeof(Kind))};     \      typedef n<i> type;                                                         \  };                                                                             \                                                                                 \  template<class Type,class Kind,class A0,class A1,class A2,class A3,class A4,   \                                 class A5>                                       \      struct Class<Type,Kind,p<A0,p<A1,p<A2,p<A3,p<A4,p<A5>                      \      > > > > > >                                                                \  {                                                                              \      enum{i=(sizeof(Type().Func(A0(),A1(),A2(),A3(),A4(),A5()))!=sizeof(Kind))};\      typedef n<i> type;                                                         \  };                                                                             \                                                                                 \  template<class Type,class Kind,class A0,class A1,class A2,class A3,class A4,   \                                 class A5,class A6>                              \      struct Class<Type,Kind,p<A0,p<A1,p<A2,p<A3,p<A4,p<A5,p<A6>                 \      > > > > > > >                                                              \  {                                                                              \      enum{i=(sizeof(Type().Func(A0(),A1(),A2(),A3(),A4(),A5(),                  \                                 A6()))!=sizeof(Kind))};                         \      typedef n<i> type;                                                         \  };                                                                             \                                                                                 \  template<class Type,class Kind,class A0,class A1,class A2,class A3,class A4,   \                                 class A5,class A6,class A7>                     \      struct Class<Type,Kind,p<A0,p<A1,p<A2,p<A3,p<A4,p<A5,p<A6,p<A7>            \      > > > > > > > >                                                            \  {                                                                              \      enum{i=(sizeof(Type().Func(A0(),A1(),A2(),A3(),A4(),A5(),                  \                                 A6(),A7()))!=sizeof(Kind))};                    \      typedef n<i> type;                                                         \  };                                                                             \                                                                                 \  template<class Type,class Kind,class A0,class A1,class A2,class A3,class A4,   \                                 class A5,class A6,class A7,class A8>            \      struct Class<Type,Kind,p<A0,p<A1,p<A2,p<A3,p<A4,p<A5,p<A6,p<A7,p<A8>       \      > > > > > > > > >                                                          \  {                                                                              \      enum{i=(sizeof(Type().Func(A0(),A1(),A2(),A3(),A4(),A5(),                  \                                 A6(),A7(),A8()))!=sizeof(Kind))};               \      typedef n<i> type;                                                         \  };                                                                             \  template<class Type,class Kind,class A0,class A1,class A2,class A3,class A4,   \                                 class A5,class A6,class A7,class A8,class A9>   \      struct Class<Type,Kind,p<A0,p<A1,p<A2,p<A3,p<A4,p<A5,p<A6,p<A7,p<A8,p<A9>  \      > > > > > > > > > >                                                        \  {                                                                              \      enum{i=(sizeof(Type().Func(A0(),A1(),A2(),A3(),A4(),A5(),                  \                                 A6(),A7(),A8(),A9()))!=sizeof(Kind))};          \      typedef n<i> type;                                                         \  };  

    从上面的代码中可以看出:由于需要替换函数名称,所以必须给出宏的实现,否则会比较 麻烦。虽然可以采用类似于BOOST里面的preprocessor库处理宏来简化这里的重复代码,但 为了简洁,暂时不采用(我还没有研究明白)。

    下面给出封装的更好的自动化实现(函数参数数量最多为10个):

     // 注意这里的区间复合STL规范:[0,N)  template<class Type,class Kind,template<class,class,class>class Function,class N=n<10> >  class function_parameter_numbers  {      template<class T,class i>struct Filter      {          typedef typename repeat<any,i>::type ArgPS;          typedef typename Function<T,Kind,ArgPS>::type type;      };      typedef typename range<0,N::value>::type Range;  public:      typedef typename filter<Range,Type,Filter>::type type;  };  

    下面就是上面的更进一步自动化的测试用例:

     // 函数名称为on的测试  struct A  {      kind<9> on(...);// 这个函数是测试所必须的      int on(n<0>);// 一个参数      int on(n<0>,n<1>,n<2>);// 三个参数      int on(n<0>,n<1>,n<2>,n<3>);// 四个参数  };  AUTOCXX_DEFINE_FUNCTION(on,ON);// 定义测试用的函数模版  // 函数名称不是on的测试  struct B  {      kind<9> func(...);// 这个函数是测试所必须的      int func(n<0>);// 一个参数      int func(n<0>,n<1>,n<2>);// 三个参数      int func(n<0>,n<1>,n<2>,n<3>);// 四个参数  };  AUTOCXX_DEFINE_FUNCTION(func,FUNC);// 定义测试用的函数模版  // 仿函数测试  struct C  {      kind<9> operator()(...);// 这个函数是测试所必须的      int operator()(n<0>);// 一个参数      int operator()(n<0>,n<1>,n<2>);// 三个参数      int operator()(n<0>,n<1>,n<2>,n<3>);// 四个参数  };  AUTOCXX_DEFINE_FUNCTION(operator(),FUNCTOR);// 定义测试用的函数模版  
     // 最多的被测试的函数的参数数量不得多于10个,如果需要更多的支持,可以自己编写  // 默认函数名称(on)测试  typedef function_parameter_numbers<A,kind<9>,ON>::type _A;  static_assert_same<mkps<n<1>,n<3>,n<4> >::type,_A>();  // 函数名称func测试  typedef function_parameter_numbers<B,kind<9>,FUNC>::type _B;  static_assert_same<mkps<n<1>,n<3>,n<4> >::type,_B>();  // 仿函数测试  typedef function_parameter_numbers<C,kind<9>,FUNCTOR>::type _C;  static_assert_same<mkps<n<1>,n<3>,n<4> >::type,_C>();  

    这里的之所以给出探测函数参数数量的实例,是因为它比较简单而且能够为即将研究的探 测函数参数的种类形成类似于XML的层级结构的功能做好准备:)

    发表于 @ 2007年10月23日 21:52:00|评论(loading...)|编辑

    旧一篇: 自动化C++程序设计---分析C++类结构

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © pandaxcl