首页 > 编程语言 >c++ noexcept与constexpr解析

c++ noexcept与constexpr解析

时间:2023-03-14 20:32:57浏览次数:37  
标签:函数 编译 int noexcept c++ constexpr 常量


文章目录

  • ​​1. noexcept无需抛出异常​​
  • ​​2. constexpr静态编译关键字​​
  • ​​编译期常量​​
  • ​​类中constexpr​​

1. noexcept无需抛出异常

在C++中使用noexcept来标识一个函数不会抛出异常。

noexcept:noexcept默认为true的形式,即抛出异常。

void f() noexcept; // 不会抛出异常
void (*fp)() noexcept(false); //false,抛出异常

要尽量使用noexcept而不是throw。

throw抛出异常:

int m_div(int a,int b)throw(...)    //throw表示接收任何类型的异常
{
if (b==0)
{
throw(1); //除数为零,则操作非法,抛出异常
}
return a/b;
}

noexcept抛出异常:

int m_div(int a,int b)noexcept(false) //允许抛出异常 
{
if (b==0)
{
throw(1); //除数为零,则操作非法,抛出异常
}
return a/b;
}

2. constexpr静态编译关键字

constexpr所表示的是它所声明的变量或者函数,都在静态编译时就已经完成。

程序的运行过程: 编译 ---- 链接 ---- 执行

使用constexpr表示在编译阶段编译器就已经知道了这个变量或者函数的值。

编译期常量

在我们定义数组的时候:给一个变量当作数组的大小是错误的,因为这是一个变量,不是一个常量表达式,数组只接收常量表达式作为初始大小。

int arr1[5]={1,2,3,4,5}; //ok
int a=10;
int arr2[a]={1,2,3....} //error

使用constexpr:constexpr修饰此变量为一个常量表达式,即a在编译时就已经确定了,因此他是一个编译期常量,可以当作数组的大小。

constexpr int a=10;
int arr[a]={1,2,3,4,5....} //ok !

从函数返回常量表达式:返回值是一个常量表达式,可以用作指定数组的大小。

constexpr int func(int a)
{
return 1+2+a;
}
...
int arr[func(2)]={1,2,3,4,5}; //ok !

扩展:static_assert表示静态断言,用于确定在编译时就确定的变量的值是否正确。

如果正确,返回true ,什么都不做;错误,则返回false,显示静态断言失败。

constexpr int a=10;
static_assert(a==10,"error"); // 正确,什么都不做
static_assert(func(2)==6,"error"); //错误,显示第二个字符串的内容,实际结果应该为5

conexpr的递归:

constexpr int m_pow(int base, int exp)noexcept
{
return (exp == 0) ? 1 : base * m_pow(base, exp - 1);
}
...
constexpr int res = m_pow(2, 5);//编译时计算
static_assert(res == 32, "false");

注意:你有没有注意到,函数就一条语句? 只要你在函数中使用constexpr,则你必须保证函数就一行语句: return语句。 否则constexpr的作用就相当于没有,它就是一个普通的函数了,不是编译时常量了。

  • constexpr的声明与实现一定要在使用者的前面!
  • 使用constexpr标记的函数你怎么知道就一定执行了constexpr的功能呢? 即编译时就完成了。
  • 答案: 查看反汇编,这是调用constexpr求幂的函数,可以发现它直接把一个值赋值给了变量,完成了赋值,我们都知道普通的函数调用过程一定会经历 call 与 ret的过程,因此可以确定,他的确是在编译时就完成了!!

c++ noexcept与constexpr解析_算法


类中constexpr

在类中也可以使用constexpr,可以放在除析构函数以外,任意的成员函数中,静态成员函数,构造函数都可以。

构造函数使用constexpr: constexpr 修饰类的构造函数时:要求该构造函数的函数体必须为空,且采用初始化列表的方式为各个成员赋值时,必须使用常量表达式

class Foo
{
public:
//注意,constexpr 修饰类的构造函数时:
//要求该构造函数的函数体必须为空,且采用初始化列表的方式为各个成员赋值时,必须使用常量表达式。
constexpr Foo(int a, const char* s)noexcept
:a(a), name(s) {}
}
...
constexpr Foo a{ 10, "ylh"}; //编译时初始化

完成一个类的浅拷贝的constexpr函数:

template <typename T>
constexpr T m_copy(const T& t)noexcept
{
return t;
}
...
//如果缺少 constexpr:call m_copy<Foo> (07FF7B96F13DEh) 说明这就是一个普通的函数
//如果带上 constexpr,则会发现不会调用call,即成功实现了常量表达式函数
constexpr Foo b = m_copy(a); // OK a在上面已经通过constexpr调用了constexpr的构造函数,因此b也通过constexpr实现了编译时拷贝。

接收多个参数的constexpr函数:

constexpr Foo ExChange(const Foo& a, const Foo& b)
{
return { a.GetA() / 2,b.GetName() };
}
...
// 不会调用 call ExChange (07FF6F75013F7h)
constexpr Foo ExRes = ExChange(a, b); //ok
//使用static_assert判断正确性:
static_assert(ExRes.GetA() == 5, "测试"); //是对的,因为ExRes.GetA()在函数中是来自与a的GetA函数除以2得到的,所以是10/2得5,因此正确


标签:函数,编译,int,noexcept,c++,constexpr,常量
From: https://blog.51cto.com/u_15744744/6121101

相关文章

  • C++ 哈希表的总结与例题
    文章目录​​C++STL​​​​哈希表​​​​设计哈希集合​​​​设计哈希映射​​​​哈希集合​​​​例题一:只出现一次的数字​​​​例题二:快乐数​​​​哈希映射​​​......
  • 以下是一个使用C++实现HTTP文件下载的简单示例,其中使用了C++ 11的标准库和Boost库:
    #include<iostream>#include<fstream>#include<boost/asio.hpp>usingboost::asio::ip::tcp;intmain(){try{boost::asio::io_serviceio_se......
  • C++ 基础部分 个人笔记
    本人菜鸟,个人学习笔记,如有错误还请指教C++模板是什么C++模板是一种基于类型参数化的编程技术,使用模板可以使得程序员编写独立于具体数据类型的通用代码。通过参数化类......
  • C++_一些重要的编译参数
    1.-g编译带调试信息的可执行文件#-g告诉g++产生可供GDB使用的调试信息。g++-gtest.cpp-otest2.-O[n]优化源代码-O:同时减小代码的长度和执行时间,其效果等价于......
  • 【多线程】C++11多线程(简约但不简单) 原创
    【多线程】C++11多线程(简约但不简单) 目录​ ​一、简单使用​​​ ​1、线程参数​​​ ​2.类成员函数做为线程入口​​​ ​3.join:等待线程执......
  • C/C++班级成绩管理系统[2023-03-13]
    C/C++班级成绩管理系统[2023-03-13]4.5班级成绩管理系统题目描述对一个有N个(>=10)学生的班级,每个学生有M门(>=5)课程。该系统实现对班级成绩的录入、显示、修改、排序......
  • c/c++指针从浅入深介绍——基于数据内存分配的理解(上)
    c/c++指针从浅入深介绍——基于数据内存分配的理解(上)本文是对自我学习的一个总结以及回顾,文章内容主要是针对代码中的数据在内存中的存储情况以及存储中数值的变化来......
  • 【C++踩坑】成员函数内的静态变量
    个人记录用,一直以为成员函数内的静态变量不同实例是分别存储的。事实上是所有实例共享。#include<iostream>classTest{public:voidtest(){staticinti=......
  • c++之模版类
    一.模板类的定义函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体;意义:对于功能完全一样,只是参数类型不同的函数,能写一段通用代码是......
  • 使用Python训练好的决策树模型生成C++代码
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、决策树模型二、解析决策树模型1.模型分解2.构建决策二叉树3.生成代码3.1生成python代......