请帮助我理解这种语法(在C ++中实现静态断言)

时间:2010-06-23 06:45:57

标签: c++ templates syntax metaprogramming

此语法用作this question答案的一部分:

template <bool>
struct static_assert;

template <>
struct static_assert<true> {}; // only true is defined

#define STATIC_ASSERT(x) static_assert<(x)>()

我不懂语法。它是如何工作的?

假设我

STATIC_ASSERT(true);

它会转换为

static_assert<true>();

现在是什么?

4 个答案:

答案 0 :(得分:13)

STATIC_ASSERT(true);

确实意味着

static_assert<true>();

评估为空。 static_assert<true>只是一个没有任何成员的空结构。 static_assert<true>()创建该结构的对象,不会将其存储在任何地方。

这简单地编译并且什么都不做。

另一方面

STATIC_ASSERT(false);

装置

static_assert<false>();

导致编译错误。 static_assert没有false的专业化。所以使用一般形式。但一般形式如下:

template <bool>
struct static_assert;

这只是结构的声明,而不是它的定义。所以static_assert<false>()会导致编译错误,因为它试图创建一个未定义的结构的对象。

答案 1 :(得分:9)

static_assert<true>();制作

template <>
struct static_assert<true> {}

模板化结构专门化临时对象创建正在完成 - 对构造函数的调用以及稍后对析构函数的调用,两者都有望被优化器消除,因为它们什么都不做。由于true只有一个专门化而且没​​有模板结构的通用版本,所有评估为static_assert<false>();的结构都不会编译。

答案 2 :(得分:4)

在表达式

static_assert<true>();

由于static_assert<true>是一个类型,它将调用static_assert<true>的构造函数。由于static_assert<true>专门用于空结构,因此不会有任何影响。


然而,在

static_assert<false>();

因为static_assert<false>没有专门化,通用定义

template <bool>
struct static_assert;

将被使用。但是,static_assert<B>类型不完整。所以调用static_assert<B>的构造函数会导致编译错误。


因此,这称为“静态断言”,因为如果表达式求值为false,语句将中止编译,类似于将在运行时终止程序的normal assert() function

答案 3 :(得分:2)

嗯,我想这是关于模板专业化的。 STATIC_ASSERT(true)将成功编译,因为有一个“static_assert&lt; true&gt;”的定义(不仅仅是声明)。

编译器将拒绝STATIC_ASSERT(false),因为只有“static_assert&lt; false&gt;”的声明没有定义。

更新:对于visual studio,STATIC_ASSERT(true)没问题,但STATIC_ASSERT(false)触发错误:“错误C2514:'static_assert&lt; __ formal&gt;' :class没有构造函数[with __formal = false]“