C++11 constexpr使用
常量表达式主要是允许一些计算发生在编译时,即发生在代码编译而不是运行的时候。这是很大的优化:假如有些事情可以在编译时做,它将只做一次,而不是每次程序运行时。需要计算一个编译时已知的常量,比如特定值的sine或cosin?确实你亦可以使用库函数sin或cos,但那样你必须花费运行时的开销。使用constexpr,你可以创建一个编译时的函数,它将为你计算出你需要的数值,用户的电脑将不需要做这些工作。
为了使函数获取编译时计算的能力,你必须指定constexpr关键字到这个函数。
constexpr int multiply (int x, int y)
{
return x * y;
} // 将在编译时计算
const int val = multiply( , );
除了编译时计算的性能优化,constexpr的另外一个优势是,它允许函数被应用在以前调用宏的所有场合。
例如,你想要一个计算数组size的函数,size是10的倍数。如果不用constexpr,你需要创建一个宏或者使用模板,因为你不能用函数的返回值去声明数组的大小。但是用constexpr,你就可以调用一个constexpr函数去声明一个数组。
constexpr int getDefaultArraySize (int multiplier)
{
return * multiplier;
} int my_array[ getDefaultArraySize( ) ];
int a = ; //非常量表达式
getDefaultArraySize(a); //ok
一个constexpr有一些必须遵循的严格要求:
- 函数中只能有一个return语句(但允许包含typedefs、 using declaration && directives、静态断言等)
- 只能调用其它constexpr函数
- 只能使用全局constexpr变量
注意递归并不受限制,但只允许一个返回语句,那如何实现递归呢?可以使用三元运算符(?:)。例如,计算n的阶乘:
constexpr int factorial (int n) {
return n > ? n * factorial( n - ) : ;
}
现在你可以使用factorial(2),编译器将在编译时计算这个值,这种方式运行更巧妙的计算,与内联截然不同。你无法内联一个递归函数。
3.使用编译时对象
constexpr修饰类的构造函数,即保证如果提供给该构造函数的参数都是constexpr,那么产生的对象中的所有成员都会是constexpr,该对象也就是constexpr对象了,可用于各种只能使用constexpr的场合。注意,constexpr构造函数必须有一个空的函数体,即所有成员变量的初始化都放到初始化列表中。
假如你有一个Circle类:
class Circle
{
public:
constexpr Circle (int x, int y, int radius) : _x( x ), _y( y ), _radius( radius ) {}
constexpr double getArea () {
return _radius * _radius * 3.1415926;
}
private:
int _x;
int _y;
int _radius;
};
将构造函数和getArea声明为constexpr,这样在编译期间,便能构造一个对象并能调用getArea函数获得area:
constexpr Circle c( , , );
constexpr double area = c.getArea();
4.constexpr vs const的区别
假如你将一个成员函数标记为constexpr,则顺带也将它标记为了const。如果你将一个变量标记为constexpr,则同样它是const的。但相反并不成立,一个const的变量或函数,并不是constexpr的。
语义上:
constexpr:告诉编译器我可以是编译期间可知的,尽情的优化我吧。
const:告诉程序员没人动得了我,放心的把我传出去;或者放心的把变量交给我,我啥也不动就瞅瞅。
语法上:
constexpr是一种比const 更严格的束缚, 它修饰的表达式本身在编译期间可知, 并且编译器会尽可能的 evaluate at compile time. 在constexpr 出现之前, 可以在编译期初始化的const都是implicit constexpr. 直到c++ 11, constexpr才从const中细分出来成为一个关键字, 而 const从1983年 c++ 刚改名的时候就存在了... 如果你初学c++, 应当尽可能的, 合理的使用constexpr来帮助编译器优化代码。
C++11 constexpr使用的更多相关文章
- C++11 constexpr常量表达式
常量表达式函数 要求: 函数体内只有单一的return返回语句 例如: constexpr int data() { const int i=1; //含有除了return以外的语句 return i ...
- c++ 11 游记 之 decltype constexpr
title: c++ 11 游记 1 keyword :c++ 11 decltype constexpr 作者:titer1 zhangyu 出处:www.drysaltery.com 联系:130 ...
- constexpr与常量表达式(c++11标准)
关键字 constexpr 是C++11中引入的关键字,是指值不会改变并且在编译过程中就得到计算结果的表达式.(运行中得到结果的不能成为常量表达式,比如变量). 声明为constexpr的变量一定是一 ...
- C++11--20分钟了解C++11 (下)
20分钟了解C++11 9 override关键字 (虚函数使用) * * 避免在派生类中意外地生成新函数 */ // C++ 03 class Dog { virtual void A(int); ...
- c++新特性实验(3)声明与定义:constexpr
1.作用 constexpr 声明一个函数或变量,它的值可以在编译时出现在常量表达式之中. 2.constexpr 变量要求 其类型必须是 字面类型 (LiteralType) . 它必须被立即初始化 ...
- constexpr:编译期与运行期之间的神秘关键字
Scott Meyers在effective modern c++中提到“If there were an award for the most confusing new word in C++11 ...
- Google C++ Style Guide
Background C++ is one of the main development languages used by many of Google's open-source project ...
- Google C++ 代码规范
Google C++ Style Guide Table of Contents Header Files Self-contained Headers The #define Guard For ...
- modern-cpp-features
C++17/14/11 Overview Many of these descriptions and examples come from various resources (see Acknow ...
随机推荐
- Arduino和C51开发OLED显示屏
技术:51单片机.Arduino.OLED显示屏.U8glib 概述 OLED显示屏常常用作为智能产品的显示设备,本文简单介绍OLED显示屏的使用方法. 详细 代码下载:http://www.de ...
- DOM,浏览器,javascript,html之间的关系
来源于:https://github.com/hucheng91/myBlog/blob/master/web/dom/dom.md DOM定义 DOM可以以一种独立于平台和语言的方式访问和修改一个文 ...
- BOOST ASIO 学习专贴
本文已于20170903更新完毕,所有boost asio 代码均为本人手抄.编译器为vs2013,并且所有代码已经上传,本文下方可下载源码 为了学习boost asio库,我是从boost的官方bo ...
- HDU 1710 Binary Tree Traversals (二叉树遍历)
Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- 创建 maven maven-archetype-quickstart 项目抱错问题解决方法
问题: eclipse装m2eclipse的时候装完后创建项目的时候报错: Unable to create project from archetype org.apache.maven.arche ...
- ==和equals的简单比较
前言:==和equals这个两个东西,经常放在一块做比较,下面我也给出一个简单的例子,对他俩进行一个简单的比较,先看例子,然后在看结论.(实验环境:win7+jdk7) 1:==和equals简单比较 ...
- Spark日志清洗
日志数据清洗,主要采用spark 的定时任务,清洗出有效数据,并保存到hive数据仓库中存储.常用流程如下: 参考:https://gaojianhua.gitbooks.io/bigdata-wik ...
- bootstrap-table 的 toolbar 能去掉显示吗?
我想禁用所有的toolbar,因为我显示的要求很简单,所以不想要所有的toolbar,这样可以省掉一行,但找不到方法.谢谢! data-show-columns="false"就行 ...
- 创建一个已经存在数据的MySQL复制
1.配置master库必须开启二进制日志和分配唯一的server id·如果没设置server-id或将其设置为0,master节点会拒绝slave的连接·建议在master节点设置innodb_fl ...
- java与C++之间进行SOCKET通讯要点简要解析
原文链接: http://blog.csdn.net/hslinux/article/details/6214594 java与C++之间进行SOCKET通讯要点简要解析 hslinux 0.篇外语 ...