我正在阅读编译时断言,在网上搜索后我得到了一些我不理解的代码。
template <bool> struct CompileAssert {};
#define COMPILE_ASSERT(expr, msg) \
typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
如下所示使用此COMPILE_ASSERT。
COMPILE_ASSERT(!sizeof(T*), PassRefPtr_should_never_be_assigned_to)
但我没有得到想法。有人可以帮助我理解上面的代码。 第二个在这段代码上感到困惑
typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
#define将用以上的exssion替换 COMPILE_ASSERT(expr,msg)。但 msg [bool(expr)? 1:-1] CompileAssert&lt;(bool(expr))&gt; 的替代类型。
请有人详细解释一下。我有很多问题。
就像为什么消息(PassRefPtr_should_never_be_assigned_to)在不使用“”for char *
的情况下工作答案 0 :(得分:1)
typedef
会根据expr
的值命名合法或非法的代码。
我们说bool(expr)
是true
。在这种情况下,typedef等同于
typedef CompileAssert<true> msg[1];
这是CompileAssert<true>
结构的1元素数组,名为msg
。由于CompileAssert<bool>
是一个定义的结构,一切都很好。
但是,如果bool(expr)
为false
,则typedef将等同于以下内容:
typedef CompileAssert<false> msg[-1];
这当然是非法的(您无法创建大小为-1的数组),因此编译器将报告msg
格式错误的错误。由于msg
是宏参数,它实际上是COMPILE_ASSERT
中提供的文本,因此您的示例的错误消息可能如下所示:
Cannot create array PassRefPtr_should_never_be_assigned_to of size -1.
另请注意,C ++ 11具有内置static_assert
。
答案 1 :(得分:1)
如果将表达式传递给计算结果为false的宏,则宏将给出如下的typedef:
typedef CompileAssert<false> PassRefPtr_should_never_be_assigned_to[false ? 1 : -1];
是
typedef CompileAssert<false> PassRefPtr_should_never_be_assigned_to[-1];
因此,由于不允许使用负数组长度,编译器将为typedef发出错误,包含“msg”作为数组名称。