C++11 static_assert
C++0x中引入了static_assert这个关键字,用来做编译期间的断言,因此叫做静态断言。
其语法:static_assert(常量表达式,提示字符串)。
如果第一个参数常量表达式的值为false,会产生一条编译错误,错误位置就是该static_assert语句所在行,第二个参数就是错误提示字符串。
使用static_assert,我们可以在编译期间发现更多的错误,用编译器来强制保证一些契约,并帮助我们改善编译信息的可读性,尤其是用于模板的时候。
static_assert可以用在全局作用域中,命名空间中,类作用域中,函数作用域中,几乎可以不受限制的使用。
编译器在遇到一个static_assert语句时,通常立刻将其第一个参数作为常量表达式进行演算,但如果该常量表达式依赖于某些模板参数,则延迟到模板实例化时再进行演算,这就让检查模板参数成为了可能。
由于之前有望加入C++0x标准的concepts提案最终被否决了,因此对于检查模板参数是否符合期望的重任,就要靠static_assert来完成了,所以如何构造适当的常量表达式,将是一个值得探讨的话题。
性能方面,由于是static_assert编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失。
简单范例:
static_assert(sizeof(void *) == 4, "64-bit code generation is not supported.");
该static_assert用来确保编译仅在32位的平台上进行,不支持64位的平台,该语句可以放在文件的开头处,这样可以尽早检查,以节省失败情况下的编译时间。
另一个范例:
#include <cassert> #include <cstring> using namespace std;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; }
这里使用assert运行时断言,但如果bit_copy不被调用,我们将无法触发该断言,实际上正确产生断言的时机应该在模版实例化时,即编译时期。
使用static_assert替换assert再次编译,即可获得一个错误并显示我们指定的错误信息。
注意:static_assert的断言表达式的结果必须是在编译时期可以计算的表达式,即必须是常量表达式。如果使用变量,则会导致错误。
int positive(const int n) {static_assert(n > 0, "value must > 0");return 0; }
我们知道,C++现有的标准中,就有assert、#error两个设施,也是用来检查错误的,还有一些第三方的静态断言实现。
assert是运行期断言,它用来发现运行期间的错误,不能提前到编译期发现错误,也不具有强制性,也谈不上改善编译信息的可读性,既然是运行期检查,对性能当然是有影响的,所以经常在发行版本中,assert都会被关掉;
#error可看做预编译期断言,甚至都算不上断言,仅仅能在预编译时显示一个错误信息,它能做的不多,可以配合#ifdef/ifndef参与预编译的条件检查,由于它无法获得编译信息,当然就做不了更进一步分析了。
在stastic_assert提交到C++0x标准之前,为了弥补assert和#error的不足,出现了一些第三方解决方案,可以作编译期的静态检查,例如:BOOST_STATIC_ASSERT和LOKI_STATIC_CHECK,但由于它们都是利用了一些编译器的隐晦特性实现的trick,可移植性、简便性都不是太好,还会降低编译速度,而且功能也不够完善,例如BOOST_STATIC_ASSERT就不能定义错误提示文字,而LOKI_STATIC_CHECK则要求提示文字满足C++类型定义的语法。
C++11 static_assert相关推荐
- 使用Clang作为编译器 —— Clang 语言扩展
1. 介绍 本文档描述了 Clang 提供的语言扩展.除了这里列出的语言扩展之外,Clang 还旨在支持广泛的 GCC 扩展.有关这些扩展的更多信息,请参阅 GCC手册. 2. 特性检查宏 语言扩展可 ...
- c++11中静态断言static_assert
c++11中的静态断言(static_assert) 在c++11中引入了,目的是在编译时就能检查处一些问题.写法如下: static_assert(常量表达式,提示字符串); 如果第一个参数常量表达 ...
- C++11中头文件type_traits介绍
C++11中的头文件type_traits定义了一系列模板类,在编译期获得某一参数.某一变量.某一个类等等类型信息,主要做静态检查. 此头文件包含三部分: (1).Helper类:帮助创建编译时常量的 ...
- 【C++】C++11新增关键字详解
目录 一.auto 1.auto 用来声明自动变量,表明变量存储在栈(C++11之前) 2.auto用于推断变量类型示例(C++11) 3.声明或定义函数时作为函数返回值的占位符,此时需要与关键字 d ...
- c++11的10个新特性
C++11标准由国际标准化组织(ISO)和国际电工委员会(IEC)旗下的C++标准委员会(ISO/IEC JTC1/SC22/WG21)于2011年8月12日公布[2] ,并于2011年9月出版.2 ...
- VS2010-2015对C++11/14/17特性的支持
VS2010-2015对C++11/14/17特性的支持 C++11 功能列表 Visual C++ 实现了 C++11 核心语言规范 中的绝大多数功能.许多 C++14 库功能和某些为 C++17 ...
- C++11(及现代C++风格)和快速迭代式开发
过去的一年我在微软亚洲研究院做输入法,我们的产品叫"英库拼音输入法" (下载Beta版),如果你用过"英库词典"(现已更名为必应词典),应该知道"英库 ...
- c++11 常量表达式
c++11 常量表达式 #define _CRT_SECURE_NO_WARNINGS#include <iostream> #include <string> #includ ...
- Cpp / #error、static_assert、assert 区别
一.#error 执行期间是预编译阶段,目的是配合 #ifdef / #ifndef 参与预编译的条件检查,显示一段错误信息. 二.static_assert static_assert(bool f ...
最新文章
- EBB-11、Linux启动流程
- Linux系统篇-文件系统虚拟文件系统
- 吸收塔如何提高吸收率_燕姐强烈推荐的一款燕窝饮,吸收率原来真的可以这么高!...
- linux下A免密码登录B
- HDU1872 稳定排序【稳定排序】
- 私有成员变量理解的补充
- mysql for macOS安装
- 谷歌Chrome浏览器 v0.2.149.27 Beta 提供下载
- Node.js 中 exports 和 module.exports 的区别
- iview admin 使用爬坑
- mysql 给已存在的商品数据,根据商品ID增加商品编号
- exfat最佳单元大小_回音壁构造和单元相关的个人看法
- 不要被后端糊弄了,我来告诉你网关是什么
- 实时协同编辑的实现: 编辑锁, OT算法
- 一个可以免费下载英文书籍的网站
- ITIL入门 ITSM入门 事件入门 事件管理入门
- 基于51单片机的LCD12864游戏机设计
- php网页显示中文乱码的解决办法!
- DevExpress 控件使用之XtraReport
- LAMP架构(基础篇)
热门文章
- 【Linux】VMware安装VMware Tools工具
- APACHE服务器出现No input file specified.解决方案
- visual studio 容器工具首次加载太慢 vsdbg\vs2017u5 exists, deleting 的解决方案
- EasyUI+MVC+EF简单用户管理Demo(问题及解决)
- Spring Boot前后端分离项目Session问题解决
- [Git]解决Permission denied, please try again问题
- 终极解决VS2015 安装失败问题,如 安装包损坏或丢失
- 一个如何解析XML文件? [关闭]
- 为什么要使用Ruby的attr_accessor,attr_reader和attr_writer?
- 在远程MQ上启动应用程序时,IBM MQ更改用户标识