测试环境: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. Java代码性能优化

    (1)在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面: 控制资源的使用,通过线程同步来控制资源的并 ...

  2. 【计组】《计算机组成与体系结构性能设计》William Stallings 第2部分 计算机系统 第3章 计算机功能和互连的顶层视图

    关键词 address bus 地址总线 asynchronous timing 异步时序 bus 总线 bus arbitration 总线仲裁 bus width 总线宽度 centralized ...

  3. 第三十四个知识点:描述攻击离散对数问题的baby-step/Giant-step方法

    第三十四个知识点:描述攻击离散对数问题的baby-step/Giant-step方法 Baby-step/Giant-step是Dnaiel Shanks为解决DLP问题开发的算法.DLP问题已经是许 ...

  4. javaScript系列 [09]-javaScript和JSON (拓展)

    本文输出JSON搜索和JSON转换相关的内容,是对前两篇文章的补充. JSON搜索 在特定的开发场景中,如果服务器端返回的JSON数据异常复杂(可能超过上万行),那么必然就有对JSON文档进行搜索的需 ...

  5. Java高效开发-SSH+Wireshark+tcpdump组合拳

    目标 实现抓取远程服务器的数据包在wireshark中展示,不需要频繁使用tcpdump抓包后保存为cap数据包,在进行从服务器下载进行解析: 工具 1.ssh win10默认没有开启ssh服务端的, ...

  6. SpringCloud创建Eureka Client服务注册

    1.说明 本文详细介绍微服务注册到Eureka的方法, 即Eureka Client注册到Eureka Server, 这里用任意一个Spring Cloud服务为例, 比如下面已经创建好的Confi ...

  7. RESTful测试工具RESTClient

    1.简介 RESTClient是一个用于测试RESTful Web服务的客户端, 是用Java Swing编写的基于Http协议的接口测试工具, 它可以向服务器发送各种Http请求,并显示服务器响应. ...

  8. Zookeeper使用超级用户删除带权限的节点

    1.背景 Zookeeper管理员会因为某些客户端对某些节点设置了权限,而导致在紧急的情况下无法修改这些节点感到困扰.在这种情况下,管理员可以通过Zookeeper超级用户模式访问这些节点,一旦设置了 ...

  9. Count Sequences

    \(考虑问题的转换,即把用n个球,分为r-l+2个部分,其中第1部分表示该区域的球值为l,第二部分表示该区域的球值为l+1\) \(......第r-l+2部分为不选该区域的球\) \(该问题等价于在 ...

  10. Oracle 查询NULL字段/空字符串

    简单记录一下: 工作中需要查询某个字段值为空的数据, 最开始查询的时候按照以前的思路 : 1.where 字段名=NULL,点击F8,未查到结果: 2.where 字段名='',点击F8,未查到结果: ...