3

C++11/C++14中constexpr的使用

 11 months ago
source link: https://blog.csdn.net/fengbingchun/article/details/131024200
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C++11/C++14中constexpr的使用

常量表达式(const expression)是指值不会改变并且在编译过程中就能得到计算结果的表达式。字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。

      只要有可能使用constexpr,就使用它

      C++11中constexpr的使用

constexpr是C++11中添加的一个特性,其主要思想是通过在编译时而不是运行时进行计算来提高程序的性能,将时间花在编译上,而在运行时节省时间(类似于模版元编程)。

      C++11规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化。

尽管不能使用普通函数作为constexpr变量的初始值,但C++11标准允许定义一种特殊的constexpr函数。这种函数应该足够简单以使得编译时就可以计算其结果,这样就能用constexpr函数去初始化constexpr变量了。

      一般来说,如果你认定变量是一个常量表达式,那就把它声明成constexpr类型

      所有constexpr对象都是const对象,而并非所有的const对象都是constexpr对象。如果你想让编译器提供保证,让变量拥有一个值,用于要求编译期常量的语境,那么能达到这个目的的工具是constexpr,而非const。

constexpr函数是指能用于常量表达式的函数。定义constexpr函数的方法与其它函数类似,不过要遵循几项约定:函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句。constexpr函数或构造函数被隐式地指定为内联函数

constexpr函数体内也可以包含其它语句,只要这些语句在运行时不执行任何操作就行。例如,constexpr函数中可以有空语句、类型别名以及using声明

      允许constexpr函数的返回值并非一个常量。constexpr函数不一定返回常量表达式。

和其它函数不一样,内联函数和constexpr函数可以在程序中多次定义。不过,对于某个给定的内联函数或者constexpr函数来说,它的多个定义必须完全一致。基于这个原因,内联函数和constexpr函数通常定义在头文件中

      constexpr函数只能调用其它constexpr函数,不能调用简单函数(simple function)。constexpr函数不应该是void类型。constexpr函数中不允许有前缀增量(++i),在C++14中已删除此限制。

      constexpr函数的理解

(1).constexpr函数可以用在要求编译期常量的语境中。在这样的语境中,若你传给一个constexpr函数的实参值是在编译期已知的,则结果也会在编译期间计算出来。如果任何一个实参值在编译期未知,则你的代码将无法通过编译。

(2).在调用constexpr函数时,若传入的值有一个或多个在编译期未知,则它的运作方式和普通函数无异,亦即它也是在运行期执行结果的计算。这意味着,如果函数执行的是同样的操作,仅仅应用的语境一个是要求编译期常量的,一个是用于所有其它值的话,那就不必写两个函数。constexpr函数就可以同时满足所有需求。

constexpr函数仅限于传入和返回字面类型(literal type),意思就是这样的类型能够持有编译期可以决议的值。在C++11中,所有的内建类型,除了void,都符合这个条件。但是用户自定义类型同样可能也是字面类型,因为它的构造函数和其它成员函数可能也是constexpr函数。

在C++11中,constexpr函数都隐式地被声明为const。

以下为测试代码:



newCodeMoreWhite.png

      constexpr构造函数:尽管构造函数不能是const的,但是字面值常量类的构造函数可以是constexpr函数。事实上,一个字面值常量类必须至少提供一个constexpr构造函数。

constexpr构造函数可以声明成=default的形式(或者是删除函数的形式=delete)。否则,constexpr构造函数就必须既符合构造函数的要求(意味着不能包含返回语句),又符合constexpr函数的要求(意味着它能拥有的唯一可执行语句就是返回语句)。综合这两点可知,constexpr构造函数体一般来说应该是空的。我们通过前置关键字constexpr就可以声明一个constexpr构造函数了。

      constexpr构造函数必须初始化所有数据成员,初始值或者使用constexpr构造函数,或者是一条常量表达式。

constexpr构造函数用于生成constexpr对象以及constexpr函数的参数或返回类型。

以下为测试代码:



newCodeMoreWhite.png

注:以上内容主要整理自:《C++ Primer Fifth Edition》、《Effective Modern C++》

      C++14中constexpr的使用

在C++11中,constexpr函数只能包含一组非常有限的语法,包括但不限于:typedefs、using和一条返回语句。在C++14中,允许的语法集大大扩展,包括最常见的语法,如if语句、多次返回、while或for循环等

以下为测试代码:



newCodeMoreWhite.png

      执行结果如下:

3c8512fc12fe4ad5ae9c108aa1e64f78.png

      GitHubhttps://github.com/fengbingchun/Messy_Test


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK