C++11 static_assert关键字

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11 static_assert关键字相关的知识,希望对你有一定的参考价值。

static_assert简介

我们知道,C++现有的标准中就有assert、#error两个方法是用来检查错误的,除此而外还有一些第三方的静态断言实现。

assert运行期断言,它用来发现运行期间的错误,不能提前到编译期发现错误,也不具有强制性,也谈不上改善编译信息的可读性。

既然是运行期检查,对性能肯定是有影响的,所以经常在发行版本中,assert都会被关掉。

#error可看作是预编译期断言(甚至都算不上断言),仅仅能在预编译时显示一个错误信息,可以配合#ifdef/ifndef参与预编译的条件检查。

由于它无法获得编译信息,当然,也就做不了更进一步分析了。

在stastic_assert提交到C++0x标准之前,为了弥补assert和#error的不足,出现了一些第三方解决方案,可以作编译期的静态检查:

static_assert关键字,用来做编译期间的断言,因此叫做静态断言

static_assert语法:

static_assert(常量表达式,提示字符串)

参数描述:

  • 如果第一个参数常量表达式的值为false,会产生一条编译错误,错误位置就是该static_assert语句所在行
  • 第二个参数就是错误提示字符串。

static_assert作用:

使用static_assert,我们可以在编译期间发现更多的错误,用编译器来强制保证一些契约,并帮助我们改善编译信息的可读性,尤其是用于模板的时候

static_assert可以用在全局作用域中,命名空间中,类作用域中,函数作用域中,几乎可以不受限制的使用

编译器在遇到一个static_assert语句时,通常立刻将其第一个参数作为常量表达式进行演算,但如果该常量表达式依赖于某些模板参数,则延迟到模板实例化时再进行演算,这就让检查模板参数成为了可能

由于是static_assert编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失

注意事项

注意:static_assert的断言表达式的结果必须是在编译时期可以计算的表达式,即必须是常量表达式。如果使用变量,则会导致错误。

int positive(const int n) 
    static_assert(n > 0, "value must > 0");
    return 0;

代码案例

检查模板参数示例

这里使用assert运行时断言,但如果bit_copy不被调用,我们将无法触发该断言,实际上正确产生断言的时机应该在模版实例化时,即编译时期。

#include <stdio.h>
#include <cassert>
#include <cstring>

template <typename T, typename U> int bit_copy(T& a, U& b)
    assert(sizeof(b) == sizeof(a));  //static_assert(sizeof(b) == sizeof(a), "template parameter size no equal!");
    memcpy(&a,&b,sizeof(b));
;

int main()

    int aaa = 0x2468;
    double bbb;
    bit_copy(aaa, bbb);
    
    getchar();
    return 0;

以上是关于C++11 static_assert关键字的主要内容,如果未能解决你的问题,请参考以下文章

c++11:为啥 std::forward 中的 static_assert 是必要的?

C++11老关键字的新含义(auto, using,extern)

手把手写C++服务器(13):C++11新特性之静态断言static_assert

std::any 用于仅移动模板,其中 copy-ctor 内的 static_assert 等于编译错误,但为啥呢?

是否有可能在GCC / GNU C中编写_Static_assert来在编译时验证内存中位字段的布局?

initializer_list::size() 上的 static_assert