1、C++中"/"运算:对两个整数做除法,结果仍为整数,如果它的商包含小数部分,则小树部分会被截除。

C++ Primer 第五章 P130

2、静态断言(static_assert)

简介

C++0x中引入了static_assert这个关键字,用来做编译期间的断言,因此叫做静态断言。

其语法很简单:static_assert(常量表达式,提示字符串)。

如果第一个参数常量表达式的值为真(true或者非零值),那么static_assert不做任何事情,就像它不存在一样,否则会产生一条编译错误,错误位置就是该static_assert语句所在行,错误提示就是第二个参数提示字符串。

说明

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

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

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

由于之前有望加入C++0x标准的concepts提案最终被否决了,因此对于检查模板参数是否符合期望的重任,就要靠static_assert来完成了,所以如何构造适当的常量表达式,将是一个值得探讨的话题。

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

范例

下面是一个来自MSDN的简单范例:

static_assert(sizeof(void *) == 4, "64-bit code generation is not supported.");

static_assert用来确保编译仅在32位的平台上进行,不支持64位的平台,该语句可以放在文件的开头处,这样可以尽早检查,以节省失败情况下的编译时间。

再看另一个范例:

 : struct MyClass
: {
: char m_value;
: };
:
: struct MyEmptyClass
: {
: void func();
: };
:
: // 确保MyEmptyClass是一个空类(没有任何非静态成员变量,也没有虚函数)
: static_assert(std::is_empty<MyEmptyClass>::value, "empty class needed");
:
: //确保MyClass是一个非空类
: static_assert(!std::is_empty<MyClass>::value, "non-empty class needed");
:
: template <typename T, typename U, typename V>
: class MyTemplate
: {
: // 确保模板参数T是一个非空类
: static_assert(
: !std::is_empty<T>::value,
: "T should be n non-empty class"
: );
:
: // 确保模板参数U是一个空类
: static_assert(
: std::is_empty<U>::value,
: "U should be an empty class"
: );
:
: // 确保模板参数V是从std::allocator<T>直接或间接派生而来,
: // 或者V就是std::allocator<T>
: static_assert(
: std::is_base_of<std::allocator<T>, V>::value,
: "V should inherit from std::allocator<T>"
: );
:
: };
:
: // 仅当模板实例化时,MyTemplate里面的那三个static_assert才会真正被演算,
: // 藉此检查模板参数是否符合期望
: template class MyTemplate<MyClass, MyEmptyClass, std::allocator<MyClass>>;
通过这个例子我们可以看出来,static_assert可以很灵活的使用,通过构造适当的常量表达式,我们可以检查很多东西。比如范例中std::is_emptystd::is_base_of都是C++新的标准库提供的type traits模板,我们使用这些模板可以检查很多类型信息。
 

相关比较

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

assert是运行期断言,它用来发现运行期间的错误,不能提前到编译期发现错误,也不具有强制性,也谈不上改善编译信息的可读性,既然是运行期检查,对性能当然是有影响的,所以经常在发行版本中,assert都会被关掉;

#error可看做预编译期断言,甚至都算不上断言,仅仅能在预编译时显示一个错误信息,它能做的不多,可以参与预编译的条件检查,由于它无法获得编译信息,当然就做不了更进一步分析了。

那么,在stastic_assert提交到C++0x标准之前,为了弥补assert#error的不足,出现了一些第三方解决方案,可以作编译期的静态检查,例如BOOST_STATIC_ASSERTLOKI_STATIC_CHECK,但由于它们都是利用了一些编译器的隐晦特性实现的trick,可移植性、简便性都不是太好,还会降低编译速度,而且功能也不够完善,例如BOOST_STATIC_ASSERT就不能定义错误提示文字,而LOKI_STATIC_CHECK则要求提示文字满足C++类型定义的语法。

C++除法运算 // 静态断言的更多相关文章

  1. (五)静态断言(下),static_assert

    二.静态断言与static_assert 通过上一篇,我们可以看到,断言assert宏只有在程序运行的时候才能起作用.而#error值在编译器预处理时才能起作用. 有时候,我们希望在编译时候能做一些断 ...

  2. BigDecimal除法运算出现java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result的解决办法

    BigDecimal除法运算出现java.lang.ArithmeticException: Non-terminating decimal expansion; no exact represent ...

  3. ruby 除法运算

    在Ruby中根据运算对象的值的不同进行不同的操作.除法运算符"/"的两边同为Interger对象时运算符进行整除运算,其中任意一方为Float对象时进行实数的除法运算. 7 / 2 ...

  4. C++断言与静态断言

    断言是很早之前就有的东西了,只需要引入cassert头文件即可使用.往往assert被用于检查不可能发生的行为,来确保开发者在调试阶段尽早发现“不可能”事件真的发生了,如果真的发生了,那么就表示代码的 ...

  5. C++11 静态断言(static_assert)

      简介 C++0x中引入了static_assert这个关键字,用来做编译期间的断言,因此叫做静态断言. 其语法很简单:static_assert(常量表达式,提示字符串). 如果第一个参数常量表达 ...

  6. FPGA中的除法运算及初识AXI总线

    FPGA中的硬件逻辑与软件程序的区别,相信大家在做除法运算时会有深入体会.硬件逻辑实现的除法运算会占用较多的资源,电路结构复杂,且通常无法在一个时钟周期内完成.因此FPGA实现除法运算并不是一个&qu ...

  7. SQL0419N 十进制除法运算无效,因为结果将有一个负小数位。 SQLSTATE=42911

    select case when sum(qty_sold*u.um03/u.um08) <> 0 then decimal(coalesce(sum(d.amt_sold_with_ta ...

  8. Matlab提供了两种除法运算:左除(\)和右除(/)

    Matlab提供了两种除法运算:左除(\)和右除(/).一般情况下,x=a\b是方程a*x =b的解,而x=b/a是方程x*a=b的解.例:a=[1  2  3; 4  2  6; 7  4  9]b ...

  9. java 除法运算只保留整数位的3种方式

      1.情景展示 根据提供的毫秒数进行除法运算,如果将毫秒数转换成小时,小时数不为0,则只取整数位,依此类推... 2.情况分析 可以使用3个函数实现 Math.floor(num)  只保留整数位 ...

随机推荐

  1. AtCoder:C - Nuske vs Phantom Thnook

    C - Nuske vs Phantom Thnook https://agc015.contest.atcoder.jp/tasks/agc015_c 题意: n*m的网格,每个格子可能是蓝色, 可 ...

  2. UItraIso 制作ubentu 系统失败

    设备忙,请退出所有正在运行的应用程序,按确定按钮重试. 解决方法: 不要使用UItraIso,不知道为什么一直不行.重启了电脑几次都不行.用Rufus吧 https://rufus.ie/ 注意: r ...

  3. Ruby 基础教程1-7

    函数: foo(x,y,z) foo(x,*args) foo(x,*args,c) foo(x=0,y="a") 2.0以后参数可以关键字指定 foo(x:0,y:0,z:0) ...

  4. oracle_列转行

    wmsys.wm_concat 将表中数据 如   ID   USERNAME    TYPE 1        刘                    下 1        刘           ...

  5. 基于Spring的最简单的定时任务实现与配置(二)

    接上一篇,原本我以为我实现的方式很简单了,在准备写(一)的时候,就去查了查别人是怎么实现定时任务的.不查还好,这一查,发现还有更简单的.所以就会有这篇文章. 本文主要是讨论,在完成Spring 项目搭 ...

  6. 142. O(1) Check Power of 2【LintCode by java】

    Description Using O(1) time to check whether an integer n is a power of 2. Example For n=4, return t ...

  7. python3爬虫-快速入门-爬取图片和标题

    直接上代码,先来个爬取豆瓣图片的,大致思路就是发送请求-得到响应数据-储存数据,原理的话可以先看看这个 https://www.cnblogs.com/sss4/p/7809821.html impo ...

  8. mahout协同过滤算法各接口

    Mahout协同过滤算法 Mahout使用了Taste来提高协同过滤算法的实现,它是一个基于Java实现的可扩展的,高效的推荐引擎.Taste既实现了最基本的基于用户的和基于内容的推荐算法,同时也提供 ...

  9. 一个五位数ABCDE乘以9,得到EDCBA,求此五位数

    此题是面试时某面试官突然抛出的,要求逻辑分析推导,不许编码,5分钟时间算出来最终结果,当然,最终没有完全推算出来 下面是编码实现 #一个五位数ABCDE*9=EDCBA,求此数 for a in ra ...

  10. POJ 2104 K-th Number(划分树)

    Description You are working for Macrohard company in data structures department. After failing your ...