测试环境:windows10 + gcc8.1

1、constexpr产生背景

c++11以后,为了保证写出的代码比以往任何时候的执行效率都要好而进行了许多改善。其中,这种改善之一就是生成常量表达式,允许程序利用编译时的计算能力。常量表达式主要是允许一些计算发生在编译时期,而不是运行时期。这是一个很进步的优化:假如有些事情可以在编译时计算,它将只计算一次,而不是在运行时每一次都进行计算。需要计算一个编译时已知的常量,比如特定的sin或者cos值,确实可以使用库函数sin和cos,但那样做是必须花费运行时的开销。此时可以使用constexpr创建一个编译时的函数,它将在编译时期计算出你需要的数值,而在用户的电脑上将无需做这些工作。

2、constexpr用法

为了使函数获取编译时计算的能力,必须给该函数指定constexpr关键字。

constexpr int multiply(int x,int y)
{
return x* y;
}
//将在编译时期计算
const int var = multiply(10,10);

除了编译时计算性能的优化,congtexpr的另外一个优势是:允许函数被应用到以前调用宏的所有场合。例如:想要计算数组size的函数,size是10的倍数。如果不用constexpr,则需要创建一个宏或者模板,因为我们不能用函数的返回值去声明数组的大小。但是我们可以调用一个constexpr函数去声明一个数组。

constexpr int getDefaultArraySize(int value)
{
return value*10;
}
int my_array[getDefaultArraySize(3)];

3、constexpr使用限制

c++11中的constexpr指定的函数返回值和参数都必须保证是字面值,而且必须有且只有一行代码(return代码)。所以通常只能通过return 三目运算符+递归来计算返回的字面值。

constexpr int factorial (int n)
{
return n > 0 ? n * factorial( n - 1 ) : 1;
}

c++14中则只要保证返回值和参数是字面值就行,函数体中可以加入更多的语句,实现了更灵活的计算。

// C++14
constexpr int factorial2(int n)
{
int result = 1;
for (int i = 1; i <= n; ++i)
result *= i;
return result;
}

c++17中lambda表达式可以被声明为constexpr。对于一个lambda而言,只要被捕获的变量是字面量类型(lieteral type),那么整个lambda也将表现为字面量类型。

//显示声明为constexpr类型
template <typename T>
constexpr auto addTo(T i){
return[i](auto j){return i+j;};
}
constexpr auto add5 = addTo(5);

当一个闭包再constexpr环境下被使用时,当它满足了constexpr的条件,则无论它有没有被显示地声明为constexpr,它仍然是constexpr的。

 //这里没有显式声明为constexpr,但依然可以表现为constexpr
auto answer = [](int n)
{
return 32 + n;
};
//在一个constexpr环境中被使用
constexpr int response = answer(10);

在c++17 中contexpr if 让以前理应被写在一起的代码,却在c++17前都没法被写在一起的情况得到了改善。传统的if-else语句是在执行期进行条件判断与选择的,因而在泛型编程中,无法使用if-else语句进行判断。在c++17中,我们可以在编译期对传统的条件语句做出相应判断,可以忽略那些完全没有被进入的语句。

注意,在老的标准中,计算使用了if,另一个分支也仍然会被编译,但在c++17中,如果使用if constexpr来替代if,编译器甚至会把编译无效条件这个过程忽略掉。

constexpr对STL库标准做出的改进:

以前在标准库中,有许多类型和函数都缺乏了constexpr的特性,这些问题在C++17中都相应做了改进。最著名的就是std::array以及用于范围获取的std::begin()和std::end()。

c++ constexpr用法的更多相关文章

  1. C++11新标准:constexpr关键字

    一.constexpr意义 将变量声明为constexpr类型以便由编译器来验证变量是否是一个常量表达式(不会改变,在编译过程中就能得到计算结果的表达式).是一种比const更强的约束,这样可以得到更 ...

  2. Google开发规范

    v0.2 - Last updated November 8, 2013 源自 Google's C++ coding style rev. 3.274 目录 由 DocToc生成     头文件   ...

  3. C++代码风格指南总结

    C++代码风格指南 代码风格的重要性 今天我收到thougthwork笔试没过的消息, 心里确实很难受, 然后师兄说我代码写得很糟糕 细想一下, 我写代码确实是随心所欲, 并没有遵循什么规范; 所以现 ...

  4. Google's C++ coding style

    v0.2 - Last updated November 8, 2013 源自 Google's C++ coding style rev. 3.274 目录 由 DocToc生成     头文件   ...

  5. Google开源项目风格指南

    Google开源项目风格指南 来源 https://github.com/zh-google-styleguide/zh-google-styleguide Google 开源项目风格指南 (中文版) ...

  6. [Guide]Google C++ Style Guide

    0.0 扉页 项目主页 Google Style Guide Google 开源项目风格指南 -中文版 0.1 译者前言 Google 经常会发布一些开源项目, 意味着会接受来自其他代码贡献者的代码. ...

  7. QT5 QSS QML界面美化视频课程系列 QT原理 项目实战 C++1X STL

    QT5 QSS QML界面美化视频课程系列 QT原理 项目实战 C++1X STL 课程1   C语言程序设计高级实用速成课程 基础+进阶+自学 课程2   C语言程序设计Windows GDI图形绘 ...

  8. const限定符、constexpr和常量表达式------c++ primer

    编译器将在编译过程中把用到const变量的地方都替换成对应的值,为了执行这种替换,编译器必须知道变量的初始值.如果程序包含多个文件,则那个用了const对象的文件都必须能访问到它的初始值才行.要做到这 ...

  9. const 和 constexpr

    在C++中,const 这个关键字用法非常灵活,导致我总会搞不清作用是干啥的.灵活使用const会大大改善程序. const 是C++的一种类型修饰符,是不可改变的不能被更新的. 1.const 修饰 ...

随机推荐

  1. 【LeetCode】883. Projection Area of 3D Shapes 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数学计算 日期 题目地址:https://leetc ...

  2. 【LeetCode】357. Count Numbers with Unique Digits 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  3. Autofac 依赖注入小知识

    Autofac 依赖注入小知识 控制反转/依赖注入 IOC/DI 依赖接口而不依赖于实现,是面向对象的六大设计原则(SOLID)之一.即依赖倒置原则(Dependence Inversion Prin ...

  4. Cookie、Session、Token、JWT

    什么是认证(Authentication)------->就是验证当前用户的身份,证明"你是你自己" 互联网中的认证: 用户名密码登录 邮箱发送登录链接 手机号接收验证码 只 ...

  5. 「Codeforces 724F」Uniformly Branched Trees

    题目大意 如果两棵树可以通过重标号后变为完全相同,那么它们就是同构的. 将中间节点定义为度数大于 \(1\) 的节点.计算由 \(n\) 个节点,其中所有的中间节点度数都为 \(d\) 的互不同构的树 ...

  6. 源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

    1. 概述 老话说的好:要善于思考,有创新意识. 言归正传,之前聊了 Springboot 的启动过程,今天来聊聊 Eureka Client 的注册过程. 2. Eureka Client 的注册过 ...

  7. Orthogonal Convolutional Neural Networks

    目录 概 主要内容 符号说明 的俩种表示 kernel orthogonal regularization orthogonal convolution Wang J, Chen Y, Chakrab ...

  8. CS5210|低成本HDMI转VGA方案|CS5210参数说明

    Capstone最新推出的一款HDMI转VGA音视频转接线或者转换器方案芯片CS5210. 其设计的优势在于内置晶振,外围电路器件较少设计简单,芯片封装集成度较高,方案BOM成本低,相比其他方案产品更 ...

  9. GDB调试-从入门到实践

    你好,我是雨乐! 在上篇文章中,我们分析了线上coredump产生的原因,其中用到了coredump分析工具gdb,这几天一直有读者在问,能不能写一篇关于gdb调试方面的文章,今天借助此文,分享一些工 ...

  10. [学习笔记] Oracle基础增删改查用法

    查询 select *|列名|表达式 from 表名 where 条件 order by 列名 select t.* from STUDENT.STUINFO t where t.stuname = ...