为了账号安全,请及时绑定邮箱和手机立即绑定

什么时候应该在C ++ 11中使用constexpr功能?

什么时候应该在C ++ 11中使用constexpr功能?

C++
慕尼黑8549860 2019-08-14 17:11:08
什么时候应该在C ++ 11中使用constexpr功能?在我看来,拥有“总是返回5的功能”正在破坏或淡化“调用函数”的含义。必须有一个原因,或者需要这种能力,或者它不会出现在C ++ 11中。为什么会这样?// preprocessor.#define MEANING_OF_LIFE 42// constants:const int MeaningOfLife = 42;// constexpr-function:constexpr int MeaningOfLife () { return 42; }在我看来,如果我编写了一个返回字面值的函数,并且我进行了代码审查,有人会告诉我,我应该声明一个常量值而不是写回返5。
查看完整描述

3 回答

?
四季花海

TA贡献1811条经验 获得超5个赞

介绍

constexpr没有引入作为告诉实现的方法,可以在需要常量表达的上下文中评估某些内容; 符合实现已经能够在C ++ 11之前证明这一点。

实现无法证明的是某段代码的意图

  • 开发人员想用这个实体表达什么?

  • 我们应该盲目地允许代码在常量表达式中使用,只是因为它恰好起作用了吗?


没有世界会是constexpr什么?

假设您正在开发一个库并意识到您希望能够计算该区间中每个整数的总和(0,N]

int f (int n) {
  return n > 0 ? n + f (n-1) : n;}

缺乏意图

如果传递的参数在转换期间是已知的,编译器可以很容易地证明上述函数在常量表达式中是可调用的。但你没有宣称这是一个意图 - 事实恰恰相反。

现在别人出现,读取你的函数,做与编译器相同的分析; “ 哦,这个函数可用于常量表达!” ,并编写以下代码。

T arr[f(10)]; // freakin' magic

优化

作为一个“令人敬畏”的库开发人员,您决定f在调用时应该缓存结果; 谁想要一遍又一遍地计算同一组价值?

int func (int n) { 
  static std::map<int, int> _cached;

  if (_cached.find (n) == _cached.end ()) 
    _cached[n] = n > 0 ? n + func (n-1) : n;

  return _cached[n];}

结果

通过引入您的愚蠢优化,您只是打破了函数的每个用法,这些用法恰好位于需要常量表达式的上下文中。

你从来没有承诺该函数的是使用常数表达式,没有constexpr就没有提供这样的承诺的方式。


那么,我们为什么需要constexpr呢?

constexpr的主要用途是声明意图

如果实体未标记为constexpr- 它从未打算用于常量表达式 ; 即使它是,我们依靠编译器来诊断这样的上下文(因为它忽略了我们的意图)。


查看完整回答
反对 回复 2019-08-14
?
白衣非少年

TA贡献1155条经验 获得超0个赞

std::numeric_limits<T>::max():无论出于何种原因,这是一种方法。constexpr这将是有益的。

另一个例子:你想声明一个std::array与另一个数组一样大的C数组(或a )。目前这样做的方法是这样的:

int x[10];int y[sizeof x / sizeof x[0]];

但是能写的不是更好:

int y[size_of(x)];

谢谢你constexpr,你可以:

template <typename T, size_t N>constexpr size_t size_of(T (&)[N]) {
    return N;}


查看完整回答
反对 回复 2019-08-14
  • 3 回答
  • 0 关注
  • 1108 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信