我正在阅读《现代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);
}
Run Code Online (Sandbox Code Playgroud)
对于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);
}
Run Code Online (Sandbox Code Playgroud)
第二个代码的唯一区别是带有参数的构造函数的用法。
在两种情况下,预期的错误消息是:
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());
Run Code Online (Sandbox Code Playgroud)
相当于
CompileTimeChecker<expr> Type();
Run Code Online (Sandbox Code Playgroud)
声明一个名为的函数Type。您可以通过使用=初始化的形式来解决此问题:
CompileTimeChecker<expr> var = Type();
Run Code Online (Sandbox Code Playgroud)
这样,就不能将其解释为声明。{}从C ++ 11开始,您还可以使用初始化。另一方面,
CompileTimeChecker<expr>(Type(0));
Run Code Online (Sandbox Code Playgroud)
是一个表达式语句,可根据需要创建对象,因为Type(0)可能无法声明函数。
从C ++ 11开始,只需使用static_assert。