C++模板编程与宏编程经验谈
C++模板编程与宏编程经验谈
有人说C 与C++的不同主要是因为C++支持模板,不要说区别是面向对象化编程,因为C同样能很好的实现对象化编程,面向对象化其实只是思想,在很多语言中都能实现,区别在于实现的难易程度,模板看似简单,但深入使用后你会发现他是多么强大的工具,即便它使一些简单问题变的更加复杂,因为我们很多人追求着一个模糊的目标,就是希望计算机能帮助我们设计更多的代码,而减轻自己一遍一遍做码农的痛苦,最终我们发现其实我们的目标是元编程,但是在通往元编程的路上我们走了很多弯路,这条弯路就是模板与宏。
很多人谈起宏与模板编程都会很模糊的认为他们的本质是相同的,又有些人觉着他们有细微差别,但又感觉不出来他们在那些方面不同,各自使用的领域。
下面我根据自己使用经验将他们做一个比较,介绍他们怎样通过自己的努力去实现我们心中的终极目标---元编程。
元编程目标 |
模板 |
宏 |
总结 |
代码不同类型元素拼装能力。 |
只能对类型和常数进行替换,如果要组装代码,只能通过类型和常数作为判断依据,进行代码组装,因此我们不得不将目标抽象成一个一个小的代码片段封装成类型,然后再组装,但是组装程序缺乏好的设计模式,所以即便诞生了boost中的MPL,但总体上却使问题变的很复杂。 |
不识别代码元素类型,将其一切元素统一认为是文本,以此进行元素替换,所以可对代码中几乎所有非预编译代码元素进行拼装。 |
宏胜出,灵活强大,简单易用,相对模板来讲不需要学习代码组装拼接设计模式。 模板MPL虽然使代码拼装变的相对容易,但是要想学习掌握这种代码拼装设计模式,却还是挺难的。 |
代码拼装的元素本身是否可以是未定或者同样是需要被组装的对象,即支持基本组装元素的符号被组装推导, y=f(x); x=g(x) y=f(g(x)) |
模板类型可以嵌套模板,拼装的元素本身可以是多个组合模板,可约束性递归拼装,在编译期模板可以自动推导出目标,所以基本拼装元素是个可被拼装的变数,因此可以实现代码按照一定规则实现自指设计,从而形成设计代码的语言(MPL)。 |
宏的元素虽然可以是包含宏且被组装,但是其所有参数必须是定数,也就是说宏的基本拼装元素在宏一开始时就被确定而不能在宏展开期间再次被自指设计,因此不容易形成设计代码的语言。(语言之所以是语言,可推导且可存储动态信息的变量是必需具备的基本能力) |
模板胜出,宏不达标。 |
多维领域设计能力,即分层的领域设计能力,也叫DSL,每个领域只关心自己领域内问题,给上层领域封装接口,使上层领域可以只关心自己邻域内为题。 |
因为其只能关注类型以及常数的代码拼装,所以 其具有很强的专注性,方法较统一,都是面向对象化编程,所以相对容易描述多维领域的模型抽象,比如通过封装智能指针,可以用较为统一的面向对象化编程思想实现数据库编程,网络编程,各种序列化技术,甚至分布式云计算,并且因为具有变量推断的能力,因此可以形成语言级别的代码组装语言(MPL) |
因为宏组装代码的类型不专注,灵活性很大,所以没有形成统一的编程模式,且因为其基本组装元素不容易被变量化的再次被设计,因此相对模板技术较难形成合理统一的多维领域设计 |
模板可作为实现DSL的关键技术,宏可以作为辅助技术加快DSL的设计。 |
上面表格中对比你会发现,这个表格是矛盾的,模板和宏其自身的优势可能成为他们的缺陷,他们的缺陷却也可能成为他们的优势,且应用领域互补,总体而言,模板部分实现了我们元编程的目标但是限制和难度都超乎想象,使得元编程设计成为一种很痛苦的事情。宏也部分达到元编程的目标,但却不能深度上达到能语言级别的去实现元编程设计。
所以我一直在思考是不是有可能借鉴模板以及宏实现一个新的元编程语言。
像宏那样,所有类型元素可参与组装,字符串,变量名,运算符,函数名,函数参数列表,逻辑表达式,类型名,类型存储格式,将这些元素都可以参与组装。
像模板一样,所有参与代码组装的元素都是可被再替换设计的变量,在代码生成过程中被计算,被合成。
像C语言语法一样能够逻辑清晰合理像个程序一样有输入有输出目标一样的执行。
然后再加入智能模板设计思路,可以识别目标代码,将其元素提取出来,可操作,自动化设计出好用的模板。
希望大家参与一同讨论分享自己的经验。
C++模板编程与宏编程经验谈的更多相关文章
- c++模板编程-typename与class关键字的区别
最近一直在研究c++模板编程,虽然有些困难,但希望能够坚持下去.今天,在书上看见一个讨论模板编程typename与class两个关键字的区别,觉得挺有意义的,就把它们给总结一下. 先看一个例子: te ...
- C++ 11可变参数接口设计在模板编程中应用的一点点总结
概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量 ...
- C++模板编程中只特化模板类的一个成员函数
模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多数成员函数的功能可能是一模一样的,特化时我们可能只需要重新实现1.2个成员函数即可.在这种情况下,如果全 ...
- C++之模板编程
当我们越来越多的使用C++的特性, 将越来越多的问题和事物抽象成对象时, 我们不难发现:很多对象都具有共性. 比如 数值可以增加.减少:字符串也可以增加减少. 它们的动作是相似的, 只是对象的类型不同 ...
- c++ 基于Policy 的 模板编程
在没真正接触c++ 模板编程之前.真的没有想到c++ 还能够这么用.最大的感触是:太灵活了,太强大了. 最初接触模板威力还是在Delta3d中,感觉里面的模板使用实在是灵活与方便,特别是dtAI中使 ...
- C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)
转自:https://www.cnblogs.com/zhoug2020/p/6581477.html 模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多 ...
- C#模板编程(2): 编写C#预处理器,让模板来的再自然一点
在<C#模板编程(1):有了泛型,为什么还需要模板?>文中,指出了C#泛型的局限性,为了突破这个局限性,我们需要模板编程.但是,C#语法以及IDE均不支持C#模板编程,怎么办呢?自己动手, ...
- 深入C++04:模板编程
模板编程 函数模板 模板意义:对类型也进行参数化: 函数模板:是不编译的,因为类型不知道 模板的实例化:函数调用点进行实例化,生成模板函数 模板函数:这才是要被编译器所编译的 函数模板.模板的特例化. ...
- python并开发编程之协程
一 引出协成 并发的本质是:切换+保存状态 CPU在运行行一个任务时,会在两种情况下切走去执行其他任务,一是该任务发生了阻塞,二是运行该任务的时间过长 yeild可以保存状态,yeild状态保存与操作 ...
随机推荐
- int64 DWORD 与cstring 互转
//int64 与cstring 互转 int64_t val = 1111111111111111111; CString str; str.Format(("%I64d"), ...
- React Mobile 搭建记录
__dirname 总是指向被执行 js 文件的绝对路径,./ 会返回你执行 node 命令的路径,例如你的工作路径. path.join()方法可以连接任意多个路径字符串.要连接的多个路径可做为参数 ...
- python 找出字符串中出现次数最多的字母
# 请大家找出s=”aabbccddxxxxffff”中 出现次数最多的字母 # 第一种方法,字典方式: s="aabbccddxxxxffff" count ={} for i ...
- Python 多组输入
#基于Python2.7 #若是想Python做到和C++中while(scanf()!=EOF)一样的多组输入效果,可以如实例所示书写 #实例实现了多组输入,计算A+B+C并输出的任务 while ...
- 一种HTML table合并单元格的思路
/** * 合并单元格 * @param table1 表格的ID * @param startRow 起始行 * @param col 合并的列号,对第几列进行合并(从0开始).如果传下来为0就是从 ...
- docker(整理中
docker镜像默认的下载地址就是docker的官网,而他们的官网在国内没有节点,时不时就被国家防火墙隔绝,会出现DNS解析不到,或者找不到镜像等狗血提示. 解决的方法有三个: 第一,就是不断尝试,因 ...
- select * from user 这条 SQL 语句,背后藏着哪些不可告人的秘密?
作为一名 Java开发人员,写 SQL 语句是常有的事,但是你知道 SQL 语句背后的处理逻辑吗?比如下面这条 SQL 语句: select * from user where id=1 执行完这条语 ...
- pyinstaller打包exe文件闪退的解决办法
pyinstaller是python下目前能打包py文件为windows下的exe文件的一个非常友好易用的库!但是,小爬每次用pyinstaller打包时也总是遇到一些难题,有时网上搜了一圈,也没看到 ...
- Spring Boot中路径及配置文件读取问题
编译时src/main/java中*.java文件会被编译成*.class文件,在classpath中创建对应目录及class文件 src/main/resources目录中的文件 ...
- Linux常用命令大全(二)
Linux常用命令大全(二) cp命令 将源文件或目录复制到目标文件或目录中 注:如果是目录,需要使用-r选项 -d 复制时保留文件链接 -f 如果现存的目标文件不能打开,则删除并重试 -i 在覆盖目 ...