C++支持如下两种不变性概念(见7.5节)。
- const:大致意思是“我承诺不改变这个值(见7.5节)”。主要用于说明接口,这样在把变量传入函数时就不必担心变量会在函数内被改变了。编译器负责确认并执行const的承诺。
- constexpr:大致意思是“在编译时求值(见10.4节)”。主要用于说明常量,作用是允许将数据置于只读内存中(不太可能被破坏)以及提升性能。
例如:
const int dmv = 17; //ldmy是一个命名的常量int var =17; //var不是常量constexpr double max1=1.4*square(dmv) //如果 square(l7)是常量表达式,则正确constexpr double max2 =1. 4square(var) //错误:var不是常量表达式const double max3= 1.4+square(var) //OK,可在运行时求值double sum(const vector<double>&); //sum不会更改它的参数的值(见225节)vector<double>v{1.2, 3.4, 4.5}; //v不是常量const double s1= sum(v); //OK:在运行时求值constexpr double s2 sum(v) //错误:sum(v)不是常量表达式
如果某个函数用在常量表达式( constant expression)中,即该表达式在编译时求值,则函数必须定义成 constexpr。例如:
constexpr double square(double x){return x*x;}
要想定义成 constexpr,函数必须非常简单:函数中只能有一条用于计算某个值的return语句。 constexpr函数可以接受非常量实参,但此时其结果将不会是一个常量表达式。当程序的上下文不需要常量表达式时,我们可以使用非常量表达式实参来调用 constexpr函数,这样我们就不用把同一个函数定义两次了:其中一个用于常量表达式,另一个用于变量。
在有的场合中,常量表达式是语言规则所必需的(如数组的界(见22.5节和73节)、case标签(见2.2.4节和94,2节)、某些模板实参(见25.2节)和使用 constexpr声明的常量)。另些情况下,编译时求值对程序的性能非常重要,所以需要使用常量。即使不考虑性能因素,不变性概念(对象状态不发生改变)也是程序设计中要考虑的一个重要问题(见10.4节)。
