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 等于编译错误,但为啥呢?