zoukankan      html  css  js  c++  java
  • c++ 编译期计算 (一)

    编译期就是编译器进行编译,产生.obj文件的所处的那一段时间(如果是广义的编译期,那么一般还包括了链接期,因为现在很多编译器都会自动调用链接器进行链接)
    执行期就是你执行某个已经链接好的程序的那段时间。 
    简单点说 : 
    “编译期”就是你在VS2008中按F7开始到 Build success 这段时间
    “执行期”就是你在VS2008中按Ctrl+F5并提供相应的参数到结果出来这段时间。
    如何实现

    模板元编程使用静态C++语言成分,编程风格类似于函数式编程( 函数式编程是一种编程模型,他将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念。 ),在模板元编程中,主要操作整型(包括布尔类型、字符类型、整数类型)常量和类型,不可以使用变量、赋值语句和迭代结构等。被操纵的实体也称为元数据(Metadata),所有元数据均可作为模板参数。 由于在模板元编程中不可以使用变量,我们只能使用typedef名字和整型常量。它们分别采用一个类型和整数值进行初始化,之后不能再赋予新的类型或数值。如果需要新的类型或数值,必须引入新的typedef名字或常量。

    语法模拟
    判断

    Template <bool cond, typename T_true, typename T_false> 
    Struct IfElse 
    { typedef T_true TypeResult; };

    Template <typename T_true, typename T_false> 
    Struct IfElse<false, T_true, T_false> //特化 bool 为 false 的情形 
    { typedef T_false TypeResult; };
    举例来说 : 

    IfElse <(1+1 == 2) , char , int >::TypeResult result; //TypeResult == char ……

    分支判断

    Template <bool > Struct If; //声明一个模版类
    Template <> 
    Struct If<false>//特化 bool 为 false 的情形 
    { static void foo() {…} }; 
    Template <> 
    Struct If<true> //特化 bool 为 true 的情形 
    { static void foo() {…} };

    Switch 实现

    template <bool, typename T_true, typename T_false> 
    struct IfElse 
    { typedef T_true TypeResult; }; 
    template <typename T_true, typename T_false> 
    struct IfElse<false,T_true,T_false> 
    { typedef T_false TypeResult; }; 
    const int c_switch_default = -1; 
    struct NullCase {}; 
    template < int _tag , typename _Type , typename _Next = NullCase> 
    struct Case 
    { enum { tag = _tag }; 
    typedef _Type Type; 
    typedef _Next Next; 
    };

    template <int _tag, typename Case > 
    struct Switch 
    { private: 
    typedef typename Case::Next NextCase;
    enum { caseTag = Case::tag, found = (caseTag == _tag || caseTag == c_switch_default)}; public: typedef typename IfElse<found, typename Case::Type, typename Switch<_tag, NextCase>::Result>::TypeResult Result; };
    template <int tag> 
    struct Switch<tag, NullCase> 
    { typedef NullCase Result; };

    struct A 
    {
    static void excute()
    {
    std::cout<<" A "<<std::endl;
    }
    };

    struct B 
    {
    static void excute()
    {
    std::cout<<" B "<<std::endl;
    }
    };

    struct C 
    {
    static void excute()
    {
    std::cout<<" Default "<<std::endl;
    }
    };

    举例来说 :

    Switch< (1+1) ,
    Case<1, A,
    Case<2, B,
    Case<c_switch_default, C> > > >::Result::excute();
    //这个时候就会输出 “ B"


    递归

    先定义一个模板, 它是递归的(一般情况下, 都会出现X<N-1>或者类似的写法) 定义递归结束的模板

    示例1:序列求和

    template <int N> struct Sum { static const int nResult = Sum<N-1>::nResult + N; }; template <> struct Sum<0> { static const int nResult = 0; };

    示例2:二进制换算十进制

    template <int N> 
    struct bin 
    { static const int value = bin<N/10>::value << 1 | (N%10); }; 
    template <> 
    struct bin<0> 
    { static const int value = 0; };

    如果有人看, 我还会坚持写下去

  • 相关阅读:
    mysql5.7创建用户授权删除用户撤销授权
    什么是分表和分区 MySql数据库分区和分表方法
    linux命令大全之watch命令详解(监测命令运行结果)
    netstat统计的tcp连接数与⁄proc⁄pid⁄fd下socket类型fd数量不一致的分析
    ss is one another utility to investigate sockets(特适合大规模tcp链接)
    /proc/net/sockstat 里的信息是什么意思?
    linux平台下server运维问题分析与定位
    strace命令解析
    MySQL常见错误代码及代码说明
    自动化部署必备技能—定制化RPM包
  • 原文地址:https://www.cnblogs.com/misserwell/p/3417766.html
Copyright © 2011-2022 走看看