条款15:只要有可能使用constexpr,就使用他

constexpr在C++中提供了编译期计算的能力,对于对象来说,它是加强版的const,确保对象在编译时已知。但并非所有const对象都是constexpr。对于函数,constexpr意味着如果参数在编译时已知,结果也可在编译时计算。例如,constexpr pow函数在编译期可以计算结果,如果参数是常量。C++11中constexpr函数有严格限制,而C++14放宽了这些限制。
摘要由CSDN通过智能技术生成

constexpr当它应用与对象时,其实就是一个加强版const;但是应用于函数时,却有着相当不同的意义;

constexpr 对象:

constexpr对象具备const属性,在编译阶段已知

int sz;							// 非constexpr变量
constexpr auto arryaSize1 = sz; // 错误!sz的数值在编译器未知
std::array<int, sz> data1;		// 错误!sz的数值在编译器未知
constexpr auto arraySize2 = 10; // 没问题,10为编译器常量
std::array<int, arraySize2> data2; // 没问题,arraySize2是个constexpr

注意:const并未提供和consexpr同样的保证,因为const对象不一定经由编译器已知值来初始化;

int sz;							// 非constexpr变量
const auto arryaSize1 = sz;     // 没问题!arraySize是sz的一个const副本
std::array<int, arryaSize1> data1;		// 错误!arryaSize1的数值在编译器未知

一言以蔽之,所有constexpr对象都是const对象,但是所有的const对象并非都是constexpr对象。如果你想让编译器提供保证,让变量拥有一个值,用于要求编译器期常量的语境,那么能达到这个目的的工具是constexpr,而非const

constexpr函数

  • constexpr函数可以用在要求编译器常量的语境当中。若你传给一个constexpr函数的实参数值是在编译期已知,则结果也会在编译期间计算出来
  • 在调用constexpr函数时,若传入的数值有一个或者多个在编译器未知,则它的运作方式和普通函数无差异

考虑一个pow函数

constexpr int pow(int base, int exp) noexcept {		// pow是一个constexpr函数,且不会抛出异常
	// ....
}

constexpr auto numConds = 5;
std::array<int, pow(3, numConds)> results;		   // results有3^numConds个元素

pow前面写的那个constexpr并不表明pow要返回一个const数值,它表明的是如果base和expr是编译器常量,pow的反馈结果就可以当一个编译器常量使用。如果baseexpr中有一个不是编译器常量,则pow的返回结果就将在执行期计算。

C++11中,constexpr函数不得包含多于一个可执行语句,即一个return语句。我们可以用条件运算符和递归解决这个问题

// C++11
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;
}

// 后面没太看明白用处

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值