C++11 static_assert
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的更多相关文章
- c++11 : static_assert和 type traits
static_assert提供一个编译时的断言检查.如果断言为真,什么也不会发生.如果断言为假,编译器会打印一个特殊的错误信息. 1 2 3 4 5 6 7 8 9 10 11 12 13 templ ...
- 《C+编程规范 101条规则、准则与最佳实践》笔记
<C+编程规范 101条规则.准则与最佳实践> 0.不要拘泥于小节(了解哪些东西不应该标准化) * 与组织内现有编码规范一致即可 * 包括但不限于: - 缩进 - 行长度 - 命名规范 - ...
- 地区sql
/*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...
- C++11 静态断言(static_assert)
简介 C++0x中引入了static_assert这个关键字,用来做编译期间的断言,因此叫做静态断言. 其语法很简单:static_assert(常量表达式,提示字符串). 如果第一个参数常量表达 ...
- C++11 assert/static_assert
assert assert 是运行期断言,它用来发现运行期间的错误,不能提前到编译期发现错误,也不具有强制性,也谈不上改善编译信息的可读性,既然是运行期检查,对性能当然是有影响的,所以经常在发行版本中 ...
- C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)
因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...
- C++11在时空性能方面的改进
C++11在时空性能方面的改进 这篇我们聊聊C++11在时间和空间上的改进点: 主要包括以下方面: 新增的高效容器:array.forward_list以及unordered containers: ...
- 推荐使用C++ 11
如果你的代码工作正常并且表现良好,你可能会想知道为什么还要使用C++ 11.当然了,使用用最新的技术感觉很好,但是事实上它是否值得呢? 在我看来,答案毫无疑问是肯定的.我在下面给出了9个理由,它们分为 ...
- C++开发者都应该使用的10个C++11特性
转载自http://blog.jobbole.com/44015/ 在C++11新标准中,语言本身和标准库都增加了很多新内容,本文只涉及了一些皮毛.不过我相信这些新特性当中有一些,应该成为所有C++开 ...
随机推荐
- 懒人小工具:T4自动生成Model,Insert,Select,Delete以及导出Excel的方法
之前写了篇文章,懒人小工具:[自动生成Model,Insert,Select,Delete以及导出Excel的方法](http://www.jianshu.com/p/d5b11589174a),但是 ...
- oracle 数据库管理--管理表空间和数据文件
一.概念表空间是数据库的逻辑组成部分.从物理上讲,数据库数据存放在数据文件中:从逻辑上讲,数据库数据则是存放在表空间中,表空间由一个或多个数据文件组成. 二.数据库的逻辑结构oracle中逻辑结构包括 ...
- Spark sql ---JSON
介绍Spark SQL的JSON支持,这是我们在Databricks中开发的一个功能,可以在Spark中更容易查询和创建JSON数据.随着网络和移动应用程序的普及,JSON已经成为Web服务API以及 ...
- C++拷贝构造函数专题
C++拷贝构造函数 在定义任何C++类时,拷贝空置操作都是必要部分,类需要控制拷贝.赋值和销毁对象时发生的行为.拷贝构造函数的用途:当创建了一个新对象时,可以用另一个对象的数据初始化这个新建的对象. ...
- 用matlab给图像加高斯噪声和椒盐噪声(不调用imnoise函数)
图像画面中的噪声,大致可以分为两类:高斯噪声和椒盐噪声.在这里,我们先看下图像中两种噪声各自的特征. 椒盐噪声:噪声幅值基本相同,但出现位置随机. 高斯噪声:图像中每一点都存在噪声,但幅值是随机分布的 ...
- JS数字金额转换为货币汉字形式
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- servlet自动获取前端页面提交数据
servlet自动获取前端页面jsp提交数据 以下是本人在学习过程中,因前端页面提交参数过多,后台servlet封装实体类过于麻烦而写的一个工具类,应用于jsp/servlet数据提交后,基于MVC+ ...
- Iframe刷新页面
window.parent.frames["name"].location="url";
- 学习如何看懂SQL Server执行计划——基本知识篇
一.基本概念 1.数据的读取 页(page)是SQL SERVER可以读写的最小I/O单位.即使只需访问一行,也要把整个页加载到缓存之中,再从缓存中读取数据.物理读取是从磁盘上读取,逻辑读取是从缓存中 ...
- zoj 1526 Big Number 数学
Big Number Time Limit: 10 Seconds Memory Limit: 32768 KB In many applications very large intege ...