宏有哪些一般函数不具备的生猛功能
宏和模板都是代码生成计数,但宏的代码生成更加黑科技。宏相比模板比较大的差异如下:宏可以定义对象宏可以放在代码的任何位置。模板只支持模板类的使用,和模板函数的调用我举个例子吧,Qt的Q_DECLARE_METATYPE宏#define Q_DECLARE_METATYPE_IMPL(TYPE) \\ QT_BEGIN_NAMESPACE \\ template \u0026lt;\u0026gt; \\ struct QMetaTypeId\u0026lt; TYPE \u0026gt; \\ { \\ enum { Defined = 1 }; \\ static int qt_metatype_id() \\ { \\ static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \\ if (const int id = metatype_id.loadAcquire()) \\ return id; \\ const int newId = qRegisterMetaType\u0026lt; TYPE \u0026gt;(#TYPE, \\ reinterpret_cast\u0026lt; TYPE *\u0026gt;(quintptr(-1))); \\ metatype_id.storeRelease(newId); \\ return newId; \\ } \\ }; \\ QT_END_NAMESPACE这个宏是什么功能呢?就是实现元编程,可以生成支持一个类型元信息的代码。这个宏有什么作用呢?主要是为QVariant类服务的QVariant类是个很神奇的类,它可以存入一个任意类型数据,只要那个类型提供默认构造函数和拷贝构造函数。然而它和容器类的区别是——它不是模板类!它不是模板类!它不是模板类!比如std::list\u0026lt;int\u0026gt;和std::list\u0026lt;double\u0026gt;并不是同一种类型,如果我要做一个类似数据总线的,传递数据的接口,这两者就不同替换而存了一个int的QVariant,和存了一个double的QVariant,是同一个类型还没搞清楚?想一想脚本语言a = list(1, 2, 3);a = 1.2323这在用于传递一些未知类型的数据时,比容器类方便得多,比void*安全得多,而且它自带类型信息,可通过id/name来标识类型在读取数据时,QVariant的类型安全是这么实现的template\u0026lt;class T\u0026gt; T QVariant::value();如果其中存储的类型,不能转换为T(隐式转换、自动转换),则返回一个默认构造的T类型对象。另外,默认提供了常见基础类型的转换,比如int、double、string之间的转换而QVariant那么多黑科技,全部依靠那个宏实现。如果你自己写了个class,想让它支持QVariant,只需要这么写class MyClass{public: MyClass(); MyClass(const MyClass\u0026amp; other); ...}Q_DECLARE_METATYPE(MyClass)这就是宏的魅力所在
■网友
内存性能宏和函数一样都具有抽象功能,但宏所表达的模块一定是可以被inlined,而函数则不一定。inlined带来两点好处:1. 有更多的优化可以被施加在代码上。跨函数边界的优化有时候会为了正确性而做得保守。2. 若干宏之间的数据将有更大可能通过寄存器传递/复用。而函数间传递的数据有很大可能要经历不必要的store-load。
推荐阅读
- 医院|感染艾滋病毒初期有哪些征兆?可以自行检查吗?共用马桶会传染吗
- 玩游戏花钱最多的有哪些游戏,哪些人
- 旅行|需要准备哪些物品?全面冬季出游清单,建议收藏带宝宝出门旅行
- 红米手机通过QQ空间的成功营销,给涉足社会化营销的企业有哪些启示
- 互联网在线音乐行业有哪些可能的盈利模式
- 直播会成为品牌传播的另一个途径么有哪些可行的方法感觉有戏又没头绪好捉急。
- 侧重业务逻辑的产品需求规格说明书,需要有哪些要点
- 大学|上海大学第8,前10名有哪些高校?上海市30所大学排名
- 学图像处理有哪些不错的书推荐
- 新浪微博创新基金投资了哪些团队
