constexpr 当它应用与对象时,其实就是一个加强版const ;但是应用于函数时,却有着相当不同的意义;
constexpr 对象:
constexpr 对象具备const 属性,在编译阶段已知
int sz;
constexpr auto arryaSize1 = sz;
std::array<int, sz> data1;
constexpr auto arraySize2 = 10;
std::array<int, arraySize2> data2;
注意:const 并未提供和consexpr 同样的保证,因为const 对象不一定经由编译器已知值来初始化;
int sz;
const auto arryaSize1 = sz;
std::array<int, arryaSize1> data1;
一言以蔽之,所有constexpr 对象都是const 对象,但是所有的const 对象并非都是constexpr 对象。如果你想让编译器提供保证,让变量拥有一个值,用于要求编译器期常量的语境,那么能达到这个目的的工具是constexpr ,而非const
constexpr 函数
constexpr 函数可以用在要求编译器常量的语境当中。若你传给一个constexpr 函数的实参数值是在编译期已知,则结果也会在编译期间计算出来- 在调用
constexpr 函数时,若传入的数值有一个或者多个在编译器未知,则它的运作方式和普通函数无差异
考虑一个pow 函数
constexpr int pow(int base, int exp) noexcept {
}
constexpr auto numConds = 5;
std::array<int, pow(3, numConds)> results;
pow 前面写的那个constexpr 并不表明pow 要返回一个const 数值,它表明的是如果base和expr是编译器常量,pow 的反馈结果就可以当一个编译器常量使用。如果base 和expr 中有一个不是编译器常量,则pow 的返回结果就将在执行期计算。
在C++11 中,constexpr 函数不得包含多于一个可执行语句,即一个return 语句。我们可以用条件运算符和递归解决这个问题
constexpr int pow(int base, int exp) noexcept {
return (exp == 0 ? 1 : base * pow(base, exp - 1));
}
C++14 限制条件放宽了,下列代码在C++11 中编译不过
constexpr int pow(int base, int exp) noexcept {
int result = 1;
for (int i = 0; i < exp; i++) {
result *= base;
}
return result;
}
// 后面没太看明白用处
|