用户操作
[即时聊天] [发私信] [加为好友]
pandaID:pandaxcl
86215次访问,排名1155,好友16人,关注者17人。
pandaxcl的文章
原创 62 篇
翻译 0 篇
转载 0 篇
评论 168 篇
pandaxcl的公告

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

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

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

EMail:pandaxcl@163.com

QQ:56637059

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

最近评论
pandaxcl:boost里面的mpl是模板元编程的基础结构,而我的这个库目的在于应用模板元到实际的编程中,有很大的区别:)
pandaxcl:呵呵:)这里的any和BOOST里面的any完全是两回事:)
不一样哈;)
whinah:还有boost.spirit,虽然编译速度慢了一点,但是效果很好
whinah:还有boost.spirit,虽然编译速度慢了一点,但是效果很好
whinah:别走火入魔了,你的这个库,boost里面都有,boost.mpl,boost.type_traits,boost.pp
文章分类
收藏
    相册
    友情连接
    小熊猫
    我的另外一个博客
    我的网站-自动化编程社区
    我的论坛-自动化编程社区论坛
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 C++自动化(模板元)编程基础与应用(2)收藏

    新一篇: C++自动化(模板元)编程基础与应用(3) | 旧一篇: C++自动化(模板元)编程基础与应用(1)

    #if 0

    在上一篇文章的最后提到了一个相对来说通用一点的LOOP循环,下面还是将上一篇文
    章中的LOOP循环代码复制如下:

    #endif
    #ifdef CODE1
    #include <iostream>
    template<size_t n> void print()
    {//这里的n是编译期的结果,可以用来定义数组的
    int a[n+1];//这么做是为了证明n是编译期常量
    std::cout << sizeof(a)/sizeof(int)-1 << " " ;
    }
    template <size_t i>struct LOOP
    {
    static void execute(){LOOP<i-1>::execute();print<i>();}
    };
    template <>struct LOOP<0>//循环终止条件
    {
    static void execute(){print<0>();}
    };
    int main()
    {
    LOOP<5>::execute();
    return 0;
    }
    #endif//CODE1
    ////////////////////////////////////////////////////////////////////////////////
    //程序运行结果如下所示:
    /*******************************************************************************
    0 1 2 3 4 5
    *******************************************************************************/
    ////////////////////////////////////////////////////////////////////////////////
    #if 0

    现在所需要考虑的问题是怎么将上面的print模板函数书写得更通用些,因为每定义一个
    新的print函数就需要重新书写两个LOOP模板,为了避免这种重复代码得书写,在此很容易想
    到的是将这个print模板函数作为模板参数传递,好了让我们开始新的尝试吧。具体得示例代
    码如下所示:

    #endif
    #ifdef CODE2
    #include <iostream>
    //下面的两个模板就比CODE1里面的LOOP模板通用多了
    template <template<size_t>class Function,size_t i> struct LOOP
    {
    static void execute()
    {
    LOOP<Function,i-1>::execute();
    Function<i>::execute();
    }
    };
    template <template<size_t>class Function> struct LOOP<Function,0>
    {
    static void execute()
    {
    Function<0>::execute();
    }
    };
    //为了模板化必须将原来的输出函数做成一个模板结构体
    template<size_t n> struct Function
    {
    static void execute()
    {//这里的n是编译期的结果,可以用来定义数组的
    int a[n+1];//这么做是为了证明n是编译期常量
    std::cout << sizeof(a)/sizeof(int)-1 << " " ;
    }
    };
    //下面是测试代码
    int main()
    {
    LOOP<Function,5>::execute();
    return 0;
    }
    #endif//CODE2
    ////////////////////////////////////////////////////////////////////////////////
    //程序运行结果如下所示:
    /*******************************************************************************
    0 1 2 3 4 5
    *******************************************************************************/
    ////////////////////////////////////////////////////////////////////////////////
    #if 0

    从CODE2的代码中可以看出,CODE2中的LOOP循环将CODE1中的print模板函数模板参数
    化之后就使得CODE2中的LOOP更通用一些了,在使用的时候仅仅只是需要按照Function的规
    范写一个模板结构就可以了,不必再书写重复结构的LOOP了,从而精简了使用时需要编写
    的代码量。但是我们注意到结果并不复合STL的前闭后开的习惯,我们也不能很容易的理解
    测试代码main函数中的LOOP<Function,n>的意义了,为了避免使用中的错误必须规定好它
    的明确的意义:

    (1)从0到n循环执行Function,并且是前闭后开的习惯

    (2)将Function执行n次,每次的整型参数从0递增1

    为了使CODE2中的LOOP循环表达的是这两个意义,必须对CODE2中的LOOP循环进行改写
    改写候的代码如下所示:

    #endif
    #ifdef CODE3
    #include <iostream>
    //下面的两个模板就比CODE1里面的LOOP模板通用多了
    template <template<size_t>class Function,size_t i> struct LOOP
    {
    static void execute()
    {
    LOOP<Function,i-1>::execute();
    Function<i-1>::execute();
    }
    };
    template <template<size_t>class Function> struct LOOP<Function,0>
    {
    static void execute(){}
    };
    //为了模板化必须将原来的输出函数做成一个模板结构体
    template<size_t n> struct Function
    {
    static void execute()
    {//这里的n是编译期的结果,可以用来定义数组的
    int a[n+1];//这么做是为了证明n是编译期常量
    std::cout << sizeof(a)/sizeof(int)-1 << " " ;
    }
    };
    //下面是测试代码
    int main()
    {
    //下面的这行代码可以按照上面的两种意义直观的理解为:
    //(1)从0到5循环执行Function,范围[0,5)
    //(2)将Function执行5次,每次的整型参数从0递增1
    LOOP<Function,5>::execute();
    return 0;
    }
    #endif//CODE3
    ////////////////////////////////////////////////////////////////////////////////
    //程序运行结果如下所示:
    /*******************************************************************************
    0 1 2 3 4
    *******************************************************************************/
    ////////////////////////////////////////////////////////////////////////////////
    #if 0

    从CODE3的运行结果来看确实满足了我们所需要表达的明确的意义,因此代码理解起来
    就非常直观了。

    从CODE3的代码中我们还是发现LOOP的起始参数固定为0,这一点实际上也是可以进一
    步改进的。下面我们就来看看如何使得起始模板参数也可以指定的,见代码CODE4:

    #endif
    #ifdef CODE4
    #include <iostream>
    //加入一个外覆层来传递额外的模板参数
    template <template<size_t>class Function,size_t start,size_t finish>
    struct LOOP
    {
    static void execute()
    {
    LOOP_BODY<finish,true>::execute();
    }
    private:
    //引入了一个布尔型的模板参数用来确定循环的终止条件
    template <size_t i,bool> struct LOOP_BODY
    {
    static void execute()
    {
    LOOP_BODY<i-1,(i-1>start)>::execute();
    Function<i-1>::execute();
    }
    };
    //循环的终止语句,停止递归以结束循环
    template <size_t i> struct LOOP_BODY<i,false>
    {
    static void execute(){}
    };
    };
    //为了模板化必须将原来的输出函数做成一个模板结构体
    template<size_t n> struct Function
    {
    static void execute()
    {//这里的n是编译期的结果,可以用来定义数组的
    int a[n+1];//这么做是为了证明n是编译期常量
    std::cout << sizeof(a)/sizeof(int)-1 << " " ;
    }
    };
    //下面是测试代码
    int main()
    {
    //下面的这行代码可以直观的理解为:
    //(1)从1到5循环执行Function,范围[1,5)
    LOOP<Function,1,5>::execute();
    //将两个输出分成两行输出
    std::cout << std::endl;
    //(1)从2到5循环执行Function,范围[2,5)
    LOOP<Function,2,5>::execute();
    return 0;
    }
    #endif//CODE4
    ////////////////////////////////////////////////////////////////////////////////
    //程序运行结果如下所示:
    /*******************************************************************************
    1 2 3 4
    2 3 4
    *******************************************************************************/
    ////////////////////////////////////////////////////////////////////////////////
    #if 0

    从CODE4中的代码我们成功的通过添加了一层外敷类实现了循环的初始值设置,但是我们
    还是应当注意CODE4中的循环步长并不能够指定,所以在这里我们通过类似的方法来实现步长
    的指定。详细代码见CODE5所示:

    #endif
    #ifdef CODE5
    #include <iostream>
    //加入一个外覆层来传递额外的模板参数
    template <template<size_t>class Function,size_t start,size_t finish,size_t step>
    struct LOOP
    {
    static void execute()
    {
    //为了能够正确的计算出实际的循环终止变量,需要对给定的终止变量
    //进行计算,以满足正确的循环语义
    LOOP_BODY<(finish/step*step+start),true>::execute();
    }
    private:
    //引入了一个布尔型的模板参数用来确定循环的终止条件
    template <size_t i,bool> struct LOOP_BODY
    {
    static void execute()
    {
    LOOP_BODY<i-step,(i-step>start)>::execute();
    Function<i-step>::execute();
    }
    };
    //循环的终止语句,停止递归以结束循环
    template <size_t i> struct LOOP_BODY<i,false>
    {
    static void execute(){}
    };
    };
    //为了模板化必须将原来的输出函数做成一个模板结构体
    template<size_t n> struct Function
    {
    static void execute()
    {//这里的n是编译期的结果,可以用来定义数组的
    int a[n+1];//这么做是为了证明n是编译期常量
    std::cout << sizeof(a)/sizeof(int)-1 << " " ;
    }
    };
    //下面是测试代码
    int main()
    {
    //下面的这行代码可以直观的理解为:
    //(1)从1到10循环执行Function,范围[1,10),步长2
    LOOP<Function,1,10,2>::execute();
    //将两个输出分成两行输出
    std::cout << std::endl;
    //(1)从2到10循环执行Function,范围[2,10),步长3
    LOOP<Function,2,10,3>::execute();
    //暂时还不能允许下面的逆向调用方式
    //LOOP<Function,10,2,-3>::execute();
    return 0;
    }
    #endif//CODE5
    ////////////////////////////////////////////////////////////////////////////////
    //程序运行结果如下所示:
    /*******************************************************************************
    1 3 5 7 9
    2 5 8
    *******************************************************************************/
    ////////////////////////////////////////////////////////////////////////////////
    #if 0

    从CODE5的代码中可以看出明显存在一个缺陷:并不能够实现逆向的循环操作。这在类
    型操作中并不是什么缺陷!因为在后续的章节的代码产生机制中并不需要逆向的循环操作
    ,所以为了使得本文尽量的简单,在这里并不讨论这个问题,这个问题留给读者思考,如
    果在本类文章的后续章节中需要这个机制,那么我会在需要的地方实现之。

    从CODE5的运行结果来看,CODE5的实现已经满足了我们日常编码的需要了,实际上用
    这里介绍的方法还可以非常容易的实现许许多多的循环语句,包括FOR循环,WHILE循环等
    等,但是需要注意的是:采用模板元编程主要是用来实现自己的功能代码的,使用这里介
    绍的循环代码已经可以满足后面进行代码生成的需要了。所以本文的静态循环代码介绍也
    可以到此打住了,不过各位有兴趣的话,可以和我联系,我非常愿意和您讨论这些话题:)

    本章完。

    在下一章里将会介绍代码的生成的机制,并通过解决一些简单的问题来说明代码生成
    为什么可以实现自动化过程。(敬请关注!)

    未完,待续...

    #endif

    发表于 @ 2006年04月16日 22:01:00|评论(loading...)|编辑

    新一篇: C++自动化(模板元)编程基础与应用(3) | 旧一篇: C++自动化(模板元)编程基础与应用(1)

    评论

    #wings 发表于2006-04-16 22:04:00  IP: 218.91.96.*
    更新好快啊,版主辛苦了啊!
    #肉骨头 发表于2006-04-17 17:41:00  IP: 221.122.38.*
    运行期灵活性不足.
    #mcs51a 发表于2006-04-21 11:26:00  IP: 58.33.229.*
    在合适的地方,合适的时间,合适的环境.....做合适的事情
    :-)
    发表评论  


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