QT_REQUIER_CONFIG
在qglobal.h中,定义了很多宏。下面这个QT_REQUIER_CONFIG,展开成:
#define QT_REQUIRE_CONFIG(feature) Q_STATIC_ASSERT_X(QT_FEATURE_##feature == 1, "Required feature " #feature " for file " __FILE__ " not available.")
注意宏定义连字符##的作用,看来Q_STATIC_ASSERT_X是一个判断句,如果feature被配置了的话,就没有问题,相反如果没有的话,就报一个错误。
就在同一个文件中,可以看到这个宏的定义:
#define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition)
继续寻根,还好就在同一个文件的上面一点就找到了:
#define Q_STATIC_ASSERT(Condition) \
enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __COUNTER__) = sizeof(QStaticAssertFailure<!!(Condition)>)}
看到了如此复杂的宏,不觉虎躯一震。继续往上找:
#define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B)
再解一次,终于到头了:
#define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B
其实就是将A和B连起来。
而对于赋值号后面的那个部分sizeof(QStaticAssertFailure<!!(Condition)>)},可以继续找到模板类的定义:
template <bool Test> class QStaticAssertFailure;
template <> class QStaticAssertFailure<true> {};
如果Condition存在的话,也就是被定义过的话,那么!!(Condition)就是1,对应上面的第二行,没有出现问题;否则是0,对应上面的第一行,第一行的意思是声明一个模板类,但是没有定义,所以sizeof为0。为了验证上面两句话的作用,可以新建一个工程,对这两句分别测试:
#include <QCoreApplication>
template<bool Test> class QStaticAssertFailure;
template <> class QStaticAssertFailure<true> {};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
sizeof(QStaticAssertFailure<>);
sizeof(QStaticAssertFailure<>);
return a.exec();
} template<bool Test> class QStaticAssertFailure;
- 如果,注释掉第2行和第7行,不能通过,理由是QStaticAssertFailure并非类模板;
- 当注释掉第三行时,第七第八行都会报incomplete type错误;
- 当无注释时,第7行报incomplete type错误;
- 当注释掉第7行,编译通过。
第3行的部分其实是一个explicit specialization,显式具体化。以下观点来自Typecool的博客:
具体化函数定义——显式具体化(explicit specialization)
当遇到特定类型参数,需要改变函数模板定义时,可以使用该方法。
以下实现需要 <第三代具体化(ISO/ANSI C++标准)>支持:
1、对于给定的函数名,可以有非模板函数、模板函数和显式具体化模板函数以及它们的重载版本。
2、显示具体化的原型和定义应以template<>打头,并通过名称来指出类型。
3、具体化将覆盖常规模板,而非模板函数将覆盖具体化和常规模板。(表明常规函数处于最高优先级,之后是显式具体化,最后是常规模板。)
c++的强大易用性的背后,确实有语法冗杂的问题。上面第三行template <> class QStaticAssertFailure<true> {};这里确实是一个显式具体化,它是针对于当Test是true的时候的一种具体定义。有了这个,在第八行就不会报错了
QT_REQUIER_CONFIG的更多相关文章
随机推荐
- Zookeeper初始(一)
量大,服务器压力大.需要用到分布式,集群. 问题1:三台机器,一个请求如何落到一台机器上?如何协调工作 问题2:集群如何选取leader? 问题3:既然是分布式,集群,一个请求只能有一台机器接接收并处 ...
- js判断输入的input内容是否为数字
有时候我们输入的input的内容需要判断一下是否是数字,所以为了更好的客户体验,在前端先处理一下: <input type="text" name="val&quo ...
- CORS在Spring中的实现
CORS: 通常情况下浏览器禁止AJAX从外部获取资源,因此就衍生了CORS这一标准体系,来实现跨域请求. CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origi ...
- Click event doesn't work on dynamically generated elements
I couldn't get live or delegate to work on a div in a lightbox (tinybox). I used setTimeout successf ...
- ROM、RAM、CPU、CACHE、FLASH的区别
内存一般采用半导体存储单元,包括随机存储器(RAM),只读存储器(ROM),以及高速缓存(CACHE).只不过因为RAM是其中最重要的存储器,所以通常所说的内存即指电脑系统中的RAM. RAM要求每时 ...
- 【实战问题】【4】Vue写的页面在微信手机端和微信web开发者工具中都能正常显示,但是在微信pc端上显示空白
原因:pc端微信浏览器不支持es6,而代码中使用了 let . 解决:将 let 改为 var(若使用 es6 语法比较多,可以进行转换,将 es6 语法转为 es5) 参考博客: 1,h5微信页面在 ...
- C++函数指针与指针函数干货
C++要是不常用,相信过四天你的指针函数与函数指针的概念就该忘个精光. 其实只要记住谁在后面谁就是哪个本质. 先了解下指针数组与数组指针吧 数组指针 就是指向数组的指针,它表示的是一个指针,它指向的是 ...
- C++ DWORD 转byte char 数组、指针
C++ DWORD 转byte char 数组.指针 byte byteData[1024]; // byte数组,示例 DWORD dwData = dwReadBytes; // dword数据, ...
- vue1.0配置路由
1,//创建 router 实例 var router = new VueRouter() 2,//components下新建home.vue组件,并在app.vue中引入模块: import hom ...
- 解决移动端真机不能下拉滚动bug
在近期的移动端开发中,发现浏览器中调试可以正常滚动,而在真机中却不能滚动了,这是为什么呢??? 总结了一下主要有一下两方面:css的设置和js的设置 1.之前有设置css的原因,下面分先说css的问题 ...