恋喵大鲤鱼 2018-06-17 11:06 采纳率: 100%
浏览 2234
已结题

C++模板元编程和编写模板有什么区别?

C++模板元编程和编写模板有什么区别?什么是模板元编程?应用场景主要有哪些?

  • 写回答

9条回答 默认 最新

  • threenewbee 2018-06-17 14:39
    关注

    很多回答都是复制粘贴一段没有什么用处的。我来说几句,如果lz满意,希望采纳,鼓励下诚实原创的回答。如果不满意,欢迎追问。

    模板元编程的意思是使用模板实现元编程,它的内涵比模版本身(java称为泛型)大得多。模版可以看作元编程最基本的运用。
    所谓元编程,就是编写一个用来编程的程序(生成代码的程序),元xx(英文meta-xxx)就是xxx的xxx。比如,元学习就是学习如何学习的方法,元数据就是描述数据的数据,等等。

    C++的模版之所以可以用来作为代码生成器,是因为它是图灵完备的,也就是说,它可以实现一切编程语言能实现的功能,关键的一条是,C++的模版可以定义参数变量。而不仅仅是类型。
    比如
    计算1+2+3...+100
    我们可以不用循环,只用递归实现,那就是
    给定一个n=100,我们可以让机器生成如下代码:
    int sum_n_1()
    {
    return 100 + sum_n_2();
    }
    注意sum_n_2这个函数也不存在,但是我们可以继续生成这么一个函数
    int sum_n_2()
    {
    return 99 + sum_n_3();
    }
    ...
    直到生成一个
    int sum_n_100()
    {
    return 1;
    }
    那么要计算1+2+3...+100,如果机器生成了以上100个函数,我们只要调用sum_n_1()是不是就算出来了呢?
    这个过程关键是这100个函数,是自动生成的,而不是我们自己一个一个写的。用C++模版得到如下代码:

     #include <iostream>
    
    template<typename T, int i=1>
    class someComputing {
    public:
        typedef volatile T* retType; // 类型计算
        enum { retValume = i + someComputing<T, i-1>::retValume }; // 数值计算,递归
        static void f() { std::cout << "someComputing: i=" << i << '\n'; }
    };
    template<typename T> // 模板特例,递归终止条件
    class someComputing<T, 0> {
    public:
        enum { retValume = 0 };
    };
    
    template<typename T>
    class codeComputing {
    public:
        static void f() { T::f(); } // 根据类型调用函数,代码计算
    };
    
    int main(){
        someComputing<int>::retType a=0;
        std::cout << sizeof(a) << '\n'; // 64-bit 程序指针
        // VS2013 默认最大递归深度500,GCC4.8 默认最大递归深度900(-ftemplate-depth=n)
        std::cout << someComputing<int, 500>::retValume << '\n'; // 1+2+...+500
        codeComputing<someComputing<int, 99>>::f();
        std::cin.get(); return 0;
    }
    

    就可以实现生成代码的功能。
    因为这个过程完全是编译器做的,所以最后生成的计算1+2+3...+100
    会自动展开函数,得到5050,也就是结果。
    那么显然当程序运行的时候,直接就输出结果了,程序不需要再求和。求和的过程提前到编译阶段就完成了。

    我们可以用解释语言来类比:
    解释语言实现了运行的时候编译
    元编程实现了编译的时候运行。

    评论

报告相同问题?

悬赏问题

  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿