<Effective Modern C++>Item 15: Use constexpr whenever possible.[constexpr 表达式]

学习+使用C++已经有挺长一段时间了,时间越长越是感叹C++语法之多之深,所以那些简历上会写精通C++的人权当是不懂事了。
constexpr是C++11新加入的一个关键字,我一直对它的用法有些困惑,所以平时写项目的时候从来不敢乱加这个关键字,在这一个Item的开头,作者也写着:

If there were an award for the most confusing new word in C++11, constexpr would probably win it.

所以很有必要对这个关键字做一个总结。

constexpr,可以明显知道是const-expression,常数表达式的意思,它表明其修饰的值不仅仅是const的,而且还是编译期就可知的,如果只是用constexpr修饰简单的表达式,那其实很好理解。

constexpr auto size=10;

意思就是size这个变量是一个编译期可知的常量,其值是10。
这里要和const区别一下:

  • const并不区别修饰对象是编译期还是运行期是常量,总之它是个常量
  • 而constexpr限制其对象是编译期就可知的常量 (如果需要通过以变量的形式指定一个array的大小,那么应该用constexpr而不是const)

所以constexpr的语义比const更强。

但是constexpr的微妙之处在于它可以用于修饰函数——当它用于修饰函数时,并不意味着函数的返回值是const或编译期可知的,这就很有趣了(这不是瞎搞事情么…这是我的第一反应)

然而真相是:

  • constexpr可用于指定上下文中传入函数的参数必须是编译期可知的常量,否则编译不会通过
  • 如果constexpr函数被调用时,传入的部分参数是运行时可知的,那么它就会表现的和普通的函数一样

有那么一个场景我们经常会碰到,至少我经常碰到:在指定std::array的大小时,我们通常希望能够按需更灵活地指定,而不是直接简单单的std::array<int,10>,std::array<double,100>,我们可以通过constexpr做到:

constexpr // pow's a constexpr func
int pow(int base, int exp) noexcept // that never throws
{
… // impl is below
}
constexpr auto numConds = 5; // # of conditions
std::array<int, pow(3, numConds)> results; // results has
// 3^numConds
// elements

以上通过重写一个constexpr类型的pow函数,数组的大小可以由(3^numConds)指定。

C++11的constexpr函数通常比简单,一般只能直接返回一个return表达式,在C++14对其进行了扩展,可以支持更复杂的if-else表达式。

这样子的话constexpr表达式就可以被推广到更多复杂的应用场景,只要满足编译期可知的条件就行了,甚至可以用于类的构造函数和类的setters(getter就不用说了只是简单的返回值而已)!

这一Item的目的就是告诉我们,尽可能的使用constexpr去修饰表达式或者函数,这意味着修饰之后的对象都可以被用于上下文需要常量的地方,这是对常量使用的一种长期保证,常量的好处就不赘述了,并且假使有错或者有误用,也能更快地在编译期发现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值