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 ...
随机推荐
- MongoDB安装实录
mongodb是nosql中的贵族,很受欢迎... 01.下载 官方:https://www.mongodb.com 社区版.企业版 https://www.mongodb.com/downloa ...
- Go map中一个很重要的特性
先看一段代码: func main() { m := make(map[int]string) m[1] = "a" m[2] = "b" m[3] = &qu ...
- MATLAB 的函数句柄
MATLAB 的函数句柄: 1.何为函数句柄? 函数句柄也是MATLAB中的一种常见的数据类型, 它的地位类似于其它计算机语言里的函数对象(Javascript,Python),函数指针(C++),或 ...
- iOS block分析
block是代码块,其本质和变量类似.不同的是代码块存储的数据是一个函数体.使用Block,就可以像其他标准函数一样,传入参数,并得到返回值. 可以把Block当做Objective-C的匿名函数,B ...
- Category在项目中的实际运用
先看两行代码:1. label2.textColor = [UIColor colorWithHexString:@"707070"]; 2. _table.header = [M ...
- 【HTML】网页中如何让DIV在网页滚动到特定位置时出现
用js或者jquery比较好实现.但你要知道,滚动到哪个特定位置,例如滚动到一个标题h3那显示这个div,那么可以用jquery算这个h3距离网页顶部的距离:$("h3").off ...
- 【Algorithm】选择排序
一. 算法描述 选择排序:比如在一个长度为N的无序数组中,在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换......第N-1 ...
- MongoDB 学习笔记(1)
数据库 一个mongodb中可以建立多个数据库. MongoDB的默认数据库为"db",该数据库存储在data目录中. MongoDB的单个实例可以容纳多个独立的数据库,每一个都有 ...
- 如何提升RDS响应速度
如果采用短连接的方式连接RDS,请在与RDS相连的云服务器上执行以下命令来提升RDS响应速度.(注:云服务器要有公网带宽) 1.安装nscd 云服务器上执行命令 Ubuntu系统执行:apt-get ...
- ASP.NET项目在IIS上使用虚拟目录
在IIS中,应用程序与虚拟目录特别容易混淆,但两者又是完全不同的概念. 应用程序是一个逻辑边界,这个边界可以分隔网站及其组成部分.虚拟目录则是一个真实的指针,这个指针指向了一个本地或远程的物理路径.虚 ...