C++11静态断言static_assert

news2024/11/18 22:22:57

C++11静态断言static_assert

  • 一、运行时断言
  • 二、静态断言的需求
  • 三、静态断言
  • 四、单参数版本的静态断言

一、运行时断言

断言(assertion)是一种编程中常用的手段。在通常情况下,断言就是将一个返回值总是需要为真的判别式放在语句中,用于排除在设计的逻辑上不应该产生的情况。比如一个函数总需要输入在一定的范围内的参数,那么程序员就可以对该参数使用断言,以迫使在该参数发生异常的时候程序退出,从而避免程序陷入逻辑的混乱。从一些意义上讲,断言并不是正常程序所必需的,不过对于程序调试来说,通常断言能够帮助程序开发者快速定位那些违反了某些前提条件的程序错误。在C++中,标准在<cassert>或<assert.h>头文件中为程序员提供了assert宏,用于在运行时进行断言。

在静态断言出现以前,我们使用的都是运行时断言,只有程序运行起来之后才有可能触发它。通常情况下运行时断言只会在Debug模式下使用,因为断言的行为比较粗暴,它会直接显示错误信息并终止程序。在Release版本中,我们通常会忽略断言(头文件cassert已经通过宏NDEBUG对Debug和Release版本做了区分处理,我们可以直接使用assert)。

#include <assert.h>

assert(expression);

二、静态断言的需求

虽然运行时断言可以满足一部分需求,但是它有一个缺点就是必须让程序运行到断言代码的位置才会触发断言。如果想在模板实例化的时候对模板实参进行约束,这种断言是无法办到的。我们需要一个能在编译阶段就给出断言的方法。可惜在C++11标准之前,没有一个标准方法来达到这个目的,我们需要利用其他特性来模拟。

三、静态断言

static_assert声明是C++11标准引入的特性,用于在程序编译阶段评估常量表达式并对返回false的表达式断言,我们称这种断言为静态断言。它基本上满足我们对静态断言的要求。

  • 所有处理必须在编译期间执行,不允许有空间或时间上的运行时成本。
  • 它必须具有简单的语法。
  • 断言失败可以显示丰富的错误诊断信息。
  • 它可以在命名空间、类或代码块内使用。
  • 失败的断言会在编译阶段报错。

C++11标准规定,使用static_assert需要传入两个实参:常量表达式和诊断消息字符串。请注意,第一个实参必须是常量表达式,因为编译器无法计算运行时才能确定结果的表达式。

#include <type_traits>

class A{};

class B:public A{};

class C{};

template<class T>
class E
{
    static_assert(std::is_base_of<A, T>::value, "A is not base of T");
};

int main(int argc, char** argv)
{
    // 使用错误,argc不是常量值
    //static_assert(argc > 0, "argc should > 0");

    // 使用正确, 由于A不是C的基类,所以将触发断言
    E<C> x;

    // 使用正确,表达式返回true,不会触发断言
    static_assert(sizeof(int) >= 4, "sizeof(int) >= 4");

    // 使用正确,A是B的父类,不会触发断言
    E<B> y;
}

在这里插入图片描述

四、单参数版本的静态断言

实际运用时,在大多数情况下使用static_assert的时候输入的诊断信息字符串就是常量表达式本身,所以让常量表达式作为诊断信息字符串参数的默认值是非常理想的。为了达到这个目的,我们可以定义一个宏:

#define LAZY_STATIC_ASSERT(B) static_assert(B, #B)

可能是该需求比较普遍的原因,2014年2月C++标准委员会就提出升级static_ assert的想法,希望让其支持单参数版本,即常量表达式,而断言输出的诊断信息为常量表达式本身。这个观点提出后得到了大多数人的认同,但是由于2014年2月C++14标准已经发布了,因此该特性不得不顺延到C++17标准中。在支持C++17标准的环境中,我们可以忽略第二个参数:

static_assert(sizeof(int) >= 4);

不过在GCC上,即使指定使用C++11标准,GCC依然支持单参数的static_assert。MSVC则不同,要使用单参数的static_assert需要指定C++17标准。


参考文献:

  1. 《深入理解C++11:C++11新特性解析与应用》
  2. 《现代C++语言核心特性解析》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle No-Fee Terms and Conditions (NFTC)到底有啥条款?

1995年Sun微系统公司推出Java至今已有28年的历史&#xff0c;由于厂商持续升级优化&#xff0c;使用场景广阔&#xff0c;生态完善&#xff0c;Java目前仍然保持着非常旺盛的生命力。 付费许可 2019年java更新了许可政策 https://www.oracle.com/java/technologies/javase/ja…

【一文速通】机器学习样本不均衡/数据分布不同怎么办?

样本不均衡是什么意思样本&#xff08;类别&#xff09;样本不平衡&#xff08;class-imbalance&#xff09;指的是分类任务中不同类别的训练样例数目差别很大的情况&#xff0c;一般地&#xff0c;样本类别比例&#xff08;Imbalance Ratio&#xff09;&#xff08;多数类vs少…

antd中Tree组件使用方法个人笔记

一、前言 最近在自己自学前端&#xff0c;不清楚学习路线&#xff0c;只能盯着公司的前端项目硬看。 公司的前端项目是react框架&#xff0c;Ant Design Pro。 之前刚把router.config.js的逻辑理顺&#xff0c;目前准备开发个简单的前端页面。 在此总结下antd中<Tree>…

【算法刷题 DAY04】剑指offer树3和队列与栈总结

JZ36 二叉搜索树与双向链表 描述 输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个排序的双向链表。如下图所示 注意: 1.要求不能创建任何新的结点&#xff0c;只能调整树中结点指针的指向。当转化完成以后&#xff0c;树中节点的左指针需要指向前驱&#xff0c;树中…

虹科新闻 | 虹科与weeve正式建立合作伙伴关系

近日&#xff0c;虹科与weeve正式建立合作伙伴关系&#xff0c;双方就工业应用自动化领域进行深入的交流与合作&#xff0c;未来将共同致力于为中国市场提供完整的物联网边缘服务解决方案&#xff0c;解决中国客户的物联网挑战。 虹科与weeve都表示十分期待这次的合作。“虹科…

day36【代码随想录】贪心算法之根据身高重建队列、用最少数量的箭引爆气球、无重叠区间

文章目录前言一、根据身高重建队列&#xff08;力扣406&#xff09;二、用最少数量的箭引爆气球&#xff08;力扣452&#xff09;三、无重叠区间&#xff08;力扣435&#xff09;前言 1、根据身高重建队列 2、用最少数量的箭引爆气球 3、无重叠区间 一、根据身高重建队列&…

魔改插线板,让电视控制周边设备开关机

一.我的需求 本人是一个极简主义风格的人&#xff0c;自从用了N1盒子刷了coreELEC 系统后&#xff0c;就不断的进行折腾&#xff0c;跟大家说下我的心路历程。 1.我家很少看电视&#xff0c;不想因为偶尔开一次电视就每个月交24块钱&#xff0c;所以把广电的机顶盒停掉了。 2.电…

TextView

1.简介 向用户显示文本的用户界面元素。 2.常见使用 2.1 设置文本内容 //xml 硬编码 <TextView android:text"文本"/> //xml 推荐放在string.xml,为了国际化考虑 <TextView android:text"string/app_name"/> //kotlin tv.text getStr…

零基础学员的shell脚本的写作思路详解

前言 这两天一直再批改学员的脚本作业&#xff0c;大多数学员写的很好&#xff0c;有的学员写的不太好。 还有一些还没有入门到学员不知道脚本该咋写。 不知道脚本怎么写的学员&#xff0c;绝大多数犯了一个错误&#xff1a;一上来就把脚本想的太复杂了。 我们今天单独聊聊这…

以研究用途搭建OpenStreetMap Virtualbox服务器

又到了新年伊始&#xff0c;下载OpenStreetMap全球数据的时候了。结果惊奇的发现&#xff0c;主站已经无法打开。仔细了解了原委&#xff0c;表示理解。好在PBF数据依旧可以获取&#xff0c;只是瓦片服务已经关停。 1.OpenStreetMap的主要问题 OpenStreetMap之所以被Blocked&…

力扣刷题记录——459.重复的字符串、461. 汉明距离、476. 数字的补数

本专栏主要记录力扣的刷题记录&#xff0c;备战蓝桥杯&#xff0c;供复盘和优化算法使用&#xff0c;也希望给大家带来帮助&#xff0c;博主是算法小白&#xff0c;希望各位大佬不要见笑&#xff0c;今天要分享的是——《459.重复的字符串、461. 汉明距离、476. 数字的补数》。…

Mysql数据库中的表

创建表 和之前的创建库差不多&#xff0c;需要多指定一个engine&#xff08;不写默认INNODB&#xff09;这个后面说 字符集还有校对规则不指定的话和库的保持一致 案例 图形化创建就不说了&#xff0c;主要就指令 # 演示关于创建表的操作 # 在db02创建表USER包含id-整形 name…

(9)go-micro微服务Redis配置

文章目录一 go-redis介绍二 go-redis安装三 redis初始化连接四 存储mail邮件五 存储token六 最后一 go-redis介绍 Redis&#xff08;Remote Dictionary Server )&#xff0c;即远程字典服务&#xff0c;是一个开源的、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库…

【验证码逆向专栏】某验二代滑块验证码逆向分析

声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; 本文章未经许可禁止转载…

svn安装与配置并集成

svn安装 客户端安装与下载 下载地址&#xff1a;https://tortoisesvn.net/downloads.zh.html 根据自身设备情况下载 1、更换安装路径&#xff0c;点击next&#xff08;如果安装路径选择不了那么先点击next在点击back就可以选择安装路径了&#xff09; 2、如果需要集成idea在下…

详解“陌生的“位段

目录 一、什么是位段&#xff1f; 二、位段的内存分配 三、位段的应用 一、什么是位段&#xff1f; C 语言允许一个结构体中以位为单位来指定其成员所占内存长度&#xff0c;这种以位为单位的成员称为"位段"或"位域"&#xff08;bit field&#xff09;…

Golang——异常和error

Go 提供了两种处理错误 方式&#xff0c; 一 种是借助 panic和 recover 的抛出捕获机制&#xff0c; 另一种使用error 错误类型 一、异常 1、go没有try/catch&#xff0c;而是使用panic/recover。 panic包出异常&#xff0c;后续代码不再执行 recover再defer中捕获异常&#x…

c++--stack,queue,priority_queue

前言 对于栈和队列我们是不陌生的&#xff0c;在数据结构阶段已经学习过&#xff0c;记得当时我们还是用c语言将它一步一步造出来&#xff0c;因为压栈与出栈正好满足数组的尾插与头删&#xff0c;数组的代价是及小的。对于队列是头出队列&#xff0c;尾插。所以就栈的实现就用…

React 学习笔记总结(七)

针对React拓展相关的学习。 文章目录一. React 项目打包二. React扩展 之 setState两种写法三. React扩展 之 lazyLoad(懒加载)四、React的 stateHook五、React 的 Effect Hook六、React 的 RefHook七、React 的 Fragment八、React 的 Context九、React 的 PureComponent1. Com…

centos配置网卡自动获取ipv4和ipv6地址

环境&#xff1a; os&#xff1a;centos7 1.背景 正常网卡通过dhcp是不会自动获取ipv6地址的&#xff0c;一般手动执行dhclient -6 <网卡名>可以获取。 现在需求是&#xff1a;实现os启动后自动获取到ipv6地址 2.方法 在网卡对应的配置文件/etc/sysconfig/network-sc…