目录
一、constexpr 关键字
constexpr 是 C++11 新引入的关键字,不过在理解其具有用法和功能之前,我们需要先理解 C++ 常量表达式。
所谓常量表达式,指的是由多个(>= 1)常量组成的表达式,换句话说,如果表达式中的成员都是常量,那么该表达式就是一个常量表达式,这也意味着,常量表达式一旦确定,其值将无法修改。
实际开发中,我们经常用到常量表达式,以定义数组为例,数组的长度就必须是一个常量表达式:
int arr1[5] = { 0, 1, 2, 3, 4 }; // ok
int arr2[2 * 5] = { 0 }; // ok
// int len = 10;
// int arr3[len] = { 0 }; // error
我们知道,C++ 程序从编写完毕到执行分为四个阶段:预处理、编译、汇编和链接,得到可执行程序后就可以运行了。值得一提的是,常量表达式和非常量表达式的计算时机不同,非常量表达式只能在程序运行阶段计算出结果;而常量表达式的计算往往发生在程序的编译阶段,这可以大大地提高程序的执行效率, 因为表达式只需要在编译阶段计算一次,节省了每次程序运行时都要计算一次的时间。
对于用 C++ 编写的程序,性能往往是永恒的追求,那么在实际开发中,如何才能判断一个表达式是否为常量表达式,进而获得在编译阶段即可执行的 "特权" 呢?除了人为判定外,还有我们一开始所提到的 C++11 新引入的 constexpr 关键字 。
constexpr 关键字的功能是使指定的常量表达式获得在程序编译阶段计算出结果的能力,而不必等到程序运行阶段。在 C++11 中,constexpr 可用于修饰普通变量、函数(包括普通函数、类的成员函数以及模板函数)以及类的构造函数。
注意:获得在程序编译阶段计算出结果的能力,并不代表 constexpr 修饰的表达式一定会在程序编译阶段被执行,具体的计算时机还是编译器说了算。
1.1 - constexpr 修饰普通变量
C++11 中,定义普通变量时可以用 constexpr 修饰,从而使该变量获得在编译阶段即可计算出结果的能力。
注意:使用 constexpr 修饰普通变量时,变量必须经过初始化且初始值必须是一个常量表达式。
constexpr int len = 10;
int arr[len] = { 0 }; // ok
在此示例中,也可以将 constexpr 替换成 const,即:
const int len = 10;
int arr[len] = { 0 }; // ok
注意:const 和 constexpr 并不相同,关于它们的区别, 后面会进行详解。
1.2 - constexpr 修饰函数
constexpr 还可以用于修饰函数的返回值,这样的函数又称为 "常量表达式函数"。
注意:constexpr 并非可以修饰任意函数的返回值,换句话说,一个函数要想成为常量表达式,必须满足如下三个条件:
-
函数必须有返回值,即函数的返回值类型不能是 void。
constexpr void func() { } // 函数的返回值类型不能是 void
-
整个函数的函数体中,除了可以包含 using 指令、typedef 语句以及 static_assert 断言以外,只能包含一条 return 返回语句,且 return 返回的表达式必须是常量表达式。
constexpr int func(int x) { constexpr int y = 0; // 函数体中只能包含一条 return 返回语句 re

本文详细介绍了C++11中的constexpr关键字,用于确保表达式在编译阶段计算,以及decltype关键字用于自动类型推导。讲述了constexpr修饰变量、函数和类构造函数的规则,以及constexpr和const的区别。同时探讨了decltype在实际编程中的应用,尤其是在泛型编程中的类型推导。

4358

被折叠的 条评论
为什么被折叠?



