C++支持如下两种不变性概念(见7.5节)。

    • const:大致意思是“我承诺不改变这个值(见7.5节)”。主要用于说明接口,这样在把变量传入函数时就不必担心变量会在函数内被改变了。编译器负责确认并执行const的承诺。
    • constexpr:大致意思是“在编译时求值(见10.4节)”。主要用于说明常量,作用是允许将数据置于只读内存中(不太可能被破坏)以及提升性能。

    例如:

    1. const int dmv = 17; //ldmy是一个命名的常量
    2. int var =17; //var不是常量
    3. constexpr double max1=1.4*square(dmv) //如果 square(l7)是常量表达式,则正确
    4. constexpr double max2 =1. 4square(var) //错误:var不是常量表达式
    5. const double max3= 1.4+square(var) //OK,可在运行时求值
    6. double sum(const vector<double>&); //sum不会更改它的参数的值(见225节)
    7. vector<double>v{1.2 3.4 4.5}; //v不是常量
    8. const double s1= sum(v); //OK:在运行时求值
    9. constexpr double s2 sum(v) //错误:sum(v)不是常量表达式

    如果某个函数用在常量表达式( constant expression)中,即该表达式在编译时求值,则函数必须定义成 constexpr。例如:

    1. constexpr double square(double x)
    2. {
    3. return x*x;
    4. }

    要想定义成 constexpr,函数必须非常简单:函数中只能有一条用于计算某个值的return语句。 constexpr函数可以接受非常量实参,但此时其结果将不会是一个常量表达式。当程序的上下文不需要常量表达式时,我们可以使用非常量表达式实参来调用 constexpr函数,这样我们就不用把同一个函数定义两次了:其中一个用于常量表达式,另一个用于变量。
    在有的场合中,常量表达式是语言规则所必需的(如数组的界(见22.5节和73节)、case标签(见2.2.4节和94,2节)、某些模板实参(见25.2节)和使用 constexpr声明的常量)。另些情况下,编译时求值对程序的性能非常重要,所以需要使用常量。即使不考虑性能因素,不变性概念(对象状态不发生改变)也是程序设计中要考虑的一个重要问题(见10.4节)。