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; };
如果有人看, 我还会坚持写下去
c++ 编译期计算 (一)的更多相关文章
- constexpr:编译期与运行期之间的神秘关键字
Scott Meyers在effective modern c++中提到“If there were an award for the most confusing new word in C++11 ...
- java编译期优化
java语言的编译期其实是一段不确定的操作过程,因为它可以分为三类编译过程: 1.前端编译:把.java文件转变为.class文件 2.后端编译:把字节码转变为机器码 3.静态提前编译:直接把*.ja ...
- JavaSe: String的编译期优化
Java的编译期优化 因为工作的原因,经常会在没有源码的情况下,对一些产品的代码进行阅读.有时在解决Bug时,在运行环境下会直接去看class文件的字节码,来确定运行中版本是否正确的. 在看字节码时, ...
- c++ 编译期与运行期
分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 转自:http://h ...
- Java编译期与运行期
编译期:是指把源码交给编译器编译成计算机可以执行的文件的过程.在Java中也就是把Java代码编成class文件的过程.编译期只是做了一些翻译功能,并没有把代码放在内存中运行起来,而只是把代码当成文本 ...
- 深入了解JVM虚拟机8:Java的编译期优化与运行期优化
java编译期优化 java语言的编译期其实是一段不确定的操作过程,因为它可以分为三类编译过程:1.前端编译:把.java文件转变为.class文件2.后端编译:把字节码转变为机器码3.静态提前编译: ...
- 1.2 - C#语言习惯 - 用运行时常量readonly而不是编译期常量const
C#中有两种类型的常量:编译期常量和运行时常量.二者有着截然不同的行为,使用不当将会带来性能上或正确性上的问题. 这两个问题最好都不要发生,不过若难以同时避免的话,那么一个略微慢一些但能保证正确的程序 ...
- java 编译期常量
今天在看书的时候遇到了一个不是很懂的名词,是在think in java 这本书的第七章讲final关键字时讲到的.然后自己在网上查了一下知道了一些. 编译器常量就是:它的值在编译期就可以确定的常量. ...
- C++编译期多态与运行期多态
前言 今日的C++不再是个单纯的"带类的C"语言,它已经发展成为一个多种次语言所组成的语言集合,其中泛型编程与基于它的STL是C++发展中最为出彩的那部分.在面向对象C++编程中, ...
随机推荐
- ./configure 时候报错c++ 编译器不能执行
./configure时报错:configure: error: C++ compiler cannot create executables .哎,今天重装测试服务器上的系统,设置好IP可以远程访问 ...
- Python中*和**的用法
好久不用Python,今天在用Python写个小工具的时候发现好些东西都快忘记了,特别是*和**. 什么情况下使用*和**呢(不是C里面的指针哦!) 当函数的参数不确定时,可以使用*args 和**k ...
- 窗口过程 - Windows程序设计(SDK)006
窗口过程 让编程改变世界 Change the world by program 内容节选: Windows 把这样一个窗口分为了客户区和非客户区,这里边白色的这一大片就是客户区,而这些标题栏.菜单栏 ...
- iOS学习之自定义UItableViewCell
在项目开发中,大部分情况下我们都需要自定义UITableViewCell, 今天就重点整理一下目前自己已经学过的自定义Cell的一些注意事项; 分步骤来写吧: 1.将自定义的Cell定义为属性; 2. ...
- 扩展Log4j支持JNDI数据源
log4j.properties配置文件: log4j.rootLogger=INFO,db #使用log4j扩展支持JNDI数据源 log4j.appender.db=com.qdgswx.log4 ...
- 初识Mybatis框架,实现增删改查等操作
此第一次接触Mybatis框架确实是有点不适应,特别是刚从Hibernate框架转转型过来,那么为什么要使用Mybatis框架,Mybatis框架和Hibernate框架又有什么异同呢? 这个问题在我 ...
- 了解 Windows Azure 存储的可伸缩性、可用性、持久性和计费
借助 Windows Azure存储,应用程序开发者及其应用程序和用户可以在云中使用可用性更高.持久性更长.可伸缩性更强的海量存储.开发者可以构建能随时随地高效访问数据的服务,在所需的时间段内存储任意 ...
- VS调试异常代码 异常:HRESULT: 0x80070057 (E_INVALIDARG) 的处理
碰到这个异常的原因很偶然: 现象:Solution在ReBuild过程中断电了,来电恢复了,重析编译整个Solution不报错,但在浏览页面时始终无法正常浏览,而在design的视图中,每个aspx的 ...
- Java 8 新特性终极版
声明:本文翻译自Java 8 Features Tutorial – The ULTIMATE Guide,翻译过程中发现并发编程网已经有同学翻译过了:Java 8 特性 – 终极手册,我还是坚持自己 ...
- Linux更换python版本 (转载)
安装完CentOS6.5(Final)后,执行#Python与#python -V,看到版本号是2.6,而且之前写的都是跑在python3.X上面的,3.X和2.X有很多不同,有兴趣的朋友可以参考下这 ...