c++ - 编译时间断言不可靠?
问题描述
我正在阅读“现代 C++ 设计”一书的第一章。特别是编译时断言。我对以下代码有一些问题:
template<bool> struct CompileTimeChecker
{
CompileTimeChecker(...) {}
};
template<> struct CompileTimeChecker<false> {};
#define STATIC_CHECK(expr, msg)\
{\
struct ERROR_##msg {ERROR_##msg() {}};\
CompileTimeChecker<((expr) != 0)>(ERROR_##msg());\
}
int main()
{
STATIC_CHECK(0, MessageNull);
STATIC_CHECK(1, MessageOne);
}
这不会引发 g++ 7.4.0 和 clang++ 6.0.0 的编译时错误。但是,以下代码确实会引发错误(如预期的那样):
template<bool> struct CompileTimeChecker
{
CompileTimeChecker(...) {}
};
template<> struct CompileTimeChecker<false> {};
#define STATIC_CHECK(expr, msg)\
{\
struct ERROR_##msg {ERROR_##msg(int i) {i;}};\
CompileTimeChecker<((expr) != 0)>(ERROR_##msg(0));\
}
int main()
{
STATIC_CHECK(0, MessageNull);
STATIC_CHECK(1, MessageOne);
}
第二个代码的唯一区别是使用了带参数的构造函数。
两种情况下的预期错误消息是:
- 克++:
no matching function for call to ‘CompileTimeChecker<false>::CompileTimeChecker(main()::ERROR_MessageNull)
- 铿锵++:
no matching conversion for functional-style cast from 'ERROR_MessageNull' to 'CompileTimeChecker<(0 != 0)>'
解决方案
这被称为最令人头疼的解析。以下声明:
CompileTimeChecker<expr>(Type());
相当于
CompileTimeChecker<expr> Type();
它声明了一个名为Type
. 您可以使用=
初始化的形式解决此问题:
CompileTimeChecker<expr> var = Type();
这样,它就不能被解释为声明。您还可以使用{}
C++11 以来的初始化。另一方面,
CompileTimeChecker<expr>(Type(0));
是一个表达式语句,它根据需要创建一个对象,因为Type(0)
不可能声明一个函数。
从 C++11 开始,只需使用static_assert
.
推荐阅读
- splunk - 使用 Splunk 读取 Squid access.log
- javascript - Javascript装箱问题留下空白
- docker - docker-compose 和 docker cli 之间的音量模式行为
- mysql - 在 phpmyadmin 中从列转换为行
- r - 我写的函数中缺少()的问题
- node.js - Joi错误验证在节点js中抛出错误
- html - 基于包含标签、文本框和 div 占位符的布局设计 HTML 表单
- javascript - 如何在给定的选择器之后停止 puppeteer 抓取?
- javascript - HEAD中的Element在connectedCallback中立即删除()本身是否安全,但在disconnectedCallback中访问自己
- python - 虚线检测 CV2 Python