【问题标题】:Please help me understand this syntax (implementing static assert in C++)请帮助我理解这个语法(在 C++ 中实现静态断言)
【发布时间】:2010-06-23 06:45:57
【问题描述】:

此语法被用作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>();

现在呢?

【问题讨论】:

    标签: c++ templates syntax metaprogramming


    【解决方案1】:
    STATIC_ASSERT(true);
    

    确实意味着

    static_assert<true>();
    

    计算结果为空。 static_assert&lt;true&gt; 只是一个没有任何成员的空结构。 static_assert&lt;true&gt;() 创建该结构的对象并且不将其存储在任何地方。

    这只是编译并且什么都不做。

    另一方面

    STATIC_ASSERT(false);
    

    意思

    static_assert<false>();
    

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

    template <bool>
    struct static_assert;
    

    这只是一个结构的声明,而不是它的定义。所以static_assert&lt;false&gt;() 在尝试创建一个未定义结构的对象时会导致编译错误。

    【讨论】:

      【解决方案2】:

      static_assert&lt;true&gt;(); 做到了

      template <>
      struct static_assert<true> {}
      

      模板结构特化临时对象创建正在完成 - 调用构造函数,然后调用析构函数,这两者都有望被优化器消除,因为它们什么都不做。由于只有 true 的特化,并且没有模板结构的通用版本,所有计算结果为 static_assert&lt;false&gt;(); 的构造都不会编译。

      【讨论】:

      • 感谢您的解释,我也发现自己迷失在这种语法中。
      【解决方案3】:

      在表达式中

      static_assert<true>();
      

      由于static_assert&lt;true&gt;是一个类型,它会调用static_assert&lt;true&gt;的构造函数。由于static_assert&lt;true&gt; 专门用于空结构,因此不会受到任何影响。


      然而,在

      static_assert<false>();
      

      因为static_assert&lt;false&gt; 没有特化,所以通用定义

      template <bool>
      struct static_assert;
      

      将被使用。但在这里,static_assert&lt;B&gt; 类型是不完整。所以调用static_assert&lt;B&gt;的构造函数会导致编译错误。


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

      【讨论】:

        【解决方案4】:

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

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

        更新:对于 Visual Studio,STATIC_ASSERT(true) 是可以的,但是 STATIC_ASSERT(false) 会触发错误:“error C2514: 'static_assert<__formal>' : class has no constructors [ with __formal = false ]”

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-25
          • 2010-10-05
          • 1970-01-01
          • 1970-01-01
          • 2011-02-21
          相关资源
          最近更新 更多