编译期编程

简介: 编译期编程

自从c++98开始,可以使用循环和路径选择执行的方式,在程序编译期执行计算。比如计算一个数是否为素数,可以使用如下的模板来实现:

template<unsigned p, unsigned d>
struct DoIsPrime
{
    static constexpr bool value = (p%d != 0) && DoIsPrime<p, d-1>::value;
};
template<unsigned p>
struct DoIsPrime<p,2>
{
    static constexpr bool value = (p%2 != 0);
};
template<unsigned p>
struct IsPrime
{
    static constexpr bool value = DoIsPrime<p,p/2>::value;
};
//call the template function
std::cout << IsPrime<9>::value << std::endl;

这里有两个问题:

  1. 为什么要声明为static?
  2. 是如何在编译期执行计算的?

先看问题1,声明为static是由于当实例化类时,类中的静态成员变量归类所有,所有对象共享统一份静态成员变量。换句话说,类特化时,不需要再定义对象即可使用该类中的静态数据。

再回答问题2,这里采用递归的方式展开计算。把展开过程梳理为:

IsPrime<9> ---> IsPrime<9,4>::value ---> 9%4 != 0 && DoIsPrime<9,3>::value ---> true && 9%3 !=0 && DoIsPrime<9,2>::value

在最后一步,由于9%3 != 0 是 false,根据经验,由前两项已经知道结果为false了,最后一个项根本不会计算,所以好像DoIsPrime<9,2>根本不会实例化。但是,这些是在编译期完成的!,因此还是会实例化。

当然还有比较清晰明了的普通函数式的写法

constexpr bool isPrime (unsigned int p)
{
    for (unsigned int d = 2; d <= p/2; ++d){
        if (p % d == 0){
            return false;
        }
    }
    return p > 1;
}
//call the template function
std::cout << isPrime(9) << std::endl;

从c++14开始,常量表达式在编译期完成计算,且支持循环等结构,不需要把所有语句在一行内完成。因此上面的函数也是在编译期完成的。

相关文章
|
IDE 编译器 开发工具
编程前的准备:编译器的安装
编程前的准备:编译器的安装
55 0
|
16天前
|
算法 编译器 C语言
《C 语言预处理指令:代码编译前的 “魔法棒”》
《C 语言预处理指令:代码编译前的 “魔法棒”》介绍了 C 语言中预处理指令的作用和使用方法,如宏定义、文件包含等,是编程初学者了解代码编译前处理过程的必备指南。
55 12
|
6月前
|
数据处理 调度 数据格式
源程序的编程理解是怎样的
从编译程序(或抽象)的视角理解源程序
|
自然语言处理 编译器 Go
揭秘Go语言编译黑盒:从源代码到神奇可执行文件的完整过程
揭秘Go语言编译黑盒:从源代码到神奇可执行文件的完整过程
71 0
|
程序员 编译器 Linux
G0 语言编译运行说明 | 学习笔记
快速学习 G0 语言编译运行说明
|
Java C语言 数据安全/隐私保护
python编译&反编译,你不知道的心机与陷阱
谈到python的文件后缀,说眼花缭乱也不为过.来看看你遇到过哪些类型! .py 如果这个不知道,呵呵...那请出门左拐,你还是充钱那个少年,没有一丝丝改变。接着打游戏去吧... .pyc 这个后缀应该算是除了python的py代码外,遇到最多的一种文件类型了。虽然python被普遍认为是一种解释性语言,但谁说它就不能被编译后执行呢?python通过compile生成的pyc文件,然后由python的虚拟机执行。相对于py文件来说,编译成pyc本质上和py没有太大区别,只是对于这个模块的加载速度提高了,并没有提高代码的执行速度,通常情况下不用主动去编译pyc文件。那pyc文件存在的意义在哪里?
1531 0
python编译&反编译,你不知道的心机与陷阱
|
存储 安全 编译器
基础C程序的开发和编译
基础C程序的开发和编译
基础C程序的开发和编译
|
Java 编译器 前端开发
烂尾工程: Java实现的汇编语言编译器
一个半拉子工程, 用Java实现的汇编语言编译器的介绍. 代码中使用中文命名. An unfinished project, an assembler implemented in Java, with naming in Chinese.
1168 0