介绍
这是《现代C++语言核心特性解析》的读书笔记。
constexpr家族的内容
书里给constexpr给了很多篇幅,但是总体来说就是一个,const表示的是不允许修改的常量,而constexpr表示的是编译期的常量。
但是逐渐被扩展到constexpr可以被用作函数,lambda,以及if constexprt,都是为了让编译期可以做更多的事情,给与开发者更多的自主性。
反正基本上想要去做一些预计算以及在模板里,用constexpr就没错了。
consteval是什么呢?
这件事情我理解来说就是constexpr被扩展定义之后的一个收缩,constexpr最初是为了定义编译期的常量,好让编译器在编译器做一些逻辑。但是逐渐扩展到函数也能放,同时运行期也能调用constexpr的函数。
那consteval做的事情就是,定义一个函数,这个函数只允许编译期运行。
说实话,有点过渡定义……
constinit的构造
因为之前做一个东西遇到过类似的依赖问题,后来用了宏+一个很取巧的类构造的方式来保证顺序。
然后C++20提供了一个更简单的方法,constinit保证在编译期就会初始化对象,相当于是最早初始化的一批对象。
- 编译期的计算都可以在编译期算好,就不会有启动的依赖关系;
- 可以被其他的非constinit对象依赖。
is_constant_evaluated
新标准还提供了一个新函数,用于区分当前逻辑运行在编译期还是运行时,可以用if constexpr去做不同的逻辑。
#include <cmath>
#include <type_traits>
constexpr double power(double b, int x) {
if (std::is_constant_evaluated() && x >= 0) {
double r = 1.0, p = b;
unsigned u = (unsigned)x;
while (u != 0) {
if (u & 1) r *= p;
u /= 2;
p *= p;
}
return r;
} else {
return std::pow(b, (double)x);
}
}
int main()
{
constexpr double kilo = power(10.0, 3); // 常量求值
int n = 3;
double mucho = power(10.0, n); // 非常量求值
return 0;
}