前言:

constexpr 是 c++ 11 引入的关键字,用来在编译阶段运行一些语句和函数,从而在编译阶段就能为常量赋值。如果某些常量的值需要运算获得,那么还可以通过定义constexpr的函数来配合运算。

用法及好处:

一般有两种用法,一种是修饰函数,另一种是修饰常量。

修饰函数:

constexpr int square(int x){
    return x*x;
}

上面这个函数表示可以在编译期间被使用。但是单单定义一个constexpr函数是没意义的,需要某种方式来触发其执行。比如

#include <stdio.h>
constexpr int square(int x){
  return x*x;
}

int main(){
  constexpr int ret = square(10);
  printf("%d\n",ret);
  return ret;
}

通过定义一个 constexpr的常量来获取 square 的返回值,以此来触发函数执行,这样的话,在编译时就已经能够确定 ret 变量的值了,那么在运行时就可以直接跳过 square(10) 的执行,这就提高了程序的运行效率。相当于把原本需要在运行期需要做的事情提前到编译期间做,把运行需要损耗的事件挪到编译期,进行了一次事件互换。如果某个函数会被反复执行很多次,那么这种时间互换能带来很大的运行时间缩减。

修饰常量:

注意到 constexpr 里面是包含 const 的,所以可以认定被 constexpr 修饰的左值是一个常量,在上面的修饰函数章节中也已经描写了。通过 constexpr 修饰的左值会在编译期就获得实际的赋值,并被放入 .rodata 内存段。

除了上述用途外,常量字符串的定义也可以使用constexpr来完成,比如

#include <stdio.h>
void printhelloworld(){
  constexpr char s[] = "hello world";
  printf("%s\n",s);
}

int main(){
  printhelloworld();
}

小结:

被constexpr修饰的语句会在编译时期被执行,因此在书写代码时需要考虑到编译期间能否保证constexpr修饰的语句都能够正确执行,如果不会,则会编译报错。

这样做的主要目的是提高运行期性能。