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++编程中, ...
随机推荐
- 我和小美的撸码日记(2)之第一个基于MVC+Jqgrid的列表页面
一.前言 “尼玛哥,上周你教我改了下OA系统UI,黄总看了很满意呀.” “不错不错,看来小美进步很大,可以提前结束试用期,到时候加工资别忘了请我吃饭呀!” “尼玛哥,你有女朋友了吗?” “ ...
- C++异常处理小例
学习程序的好方法是阅读代码和改进代码.下面的程例来自<An Overview of the C++ Programming Language>(5.1 异常和错误处理)程序用途:使用C ...
- bat命令大全
一.简单批处理内部命令简介 1.Echo 命令 打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo 命令将显示当前回显设置. 语法 echo [{on│off}] [message ...
- Android 获取文件大小
android 获取文件夹.文件的大小 以B.KB.MB.GB 为单位 FileSizeUtil public class FileSizeUtil { ;//获取文件大小单位为B的double值 ; ...
- js深入研究之自定义混合Mixin函数
<script type="text/javascript"> /* 增加函数 */ function augment(receivingClass, givingCl ...
- 【转】ubuntu中的Wine详解
原文网址:http://blog.csdn.net/iwtwiioi/article/details/10530561 什么是wine?(转自百度百科,具体看百科) wine,是一款优秀的Linux系 ...
- Android AutoCompleteTextView和MultiAutoCompleteTextView使用
Android AutoCompleteTextView和MultiAutoCompleteTextView的功能类似于百度或者Google在搜索栏输入信息的时候,弹出的与输入信息接近的提示信息: 它 ...
- SWF加解密资源索引之加密混淆篇【转】
============================ SWF加解密资源索引之加密混淆篇 ============================ [心得] swf加密混淆器(带源码) http:/ ...
- ubuntu系统修改终端提示符及设置颜色高亮
Linux终端大家想必都清楚吧,最近在使用的时候发现在进入到某个文件夹目录比较深的层次后,终端提示的绝对路径很长,这样给人的感觉很不习惯,在这里给大家介绍下如何修改终端的提示,顺便介绍下提示符的颜色: ...
- 在CentOS/RHEL 6.5上安装Chromium 谷歌浏览器
之前Google就说了,由于CentOS/RHEL 6已经是过期的系统,所以不再会有Chrome了. 虽然后来由于引起了社区的抗议,从而改口,不再提CentOS/RHEL 6是过期系统了:但是,目前在 ...