猿问

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

什么时候应该在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。


慕尼黑8549860
浏览 1109回答 3
3回答

四季花海

介绍constexpr没有引入作为告诉实现的方法,可以在需要常量表达的上下文中评估某些内容;&nbsp;符合实现已经能够在C ++ 11之前证明这一点。实现无法证明的是某段代码的意图:开发人员想用这个实体表达什么?我们应该盲目地允许代码在常量表达式中使用,只是因为它恰好起作用了吗?没有世界会是constexpr什么?假设您正在开发一个库并意识到您希望能够计算该区间中每个整数的总和(0,N]。int&nbsp;f&nbsp;(int&nbsp;n)&nbsp;{ &nbsp;&nbsp;return&nbsp;n&nbsp;>&nbsp;0&nbsp;?&nbsp;n&nbsp;+&nbsp;f&nbsp;(n-1)&nbsp;:&nbsp;n;}缺乏意图如果传递的参数在转换期间是已知的,编译器可以很容易地证明上述函数在常量表达式中是可调用的。但你没有宣称这是一个意图 - 事实恰恰相反。现在别人出现,读取你的函数,做与编译器相同的分析;&nbsp;“&nbsp;哦,这个函数可用于常量表达!”&nbsp;,并编写以下代码。T&nbsp;arr[f(10)];&nbsp;//&nbsp;freakin'&nbsp;magic优化作为一个“令人敬畏”的库开发人员,您决定f在调用时应该缓存结果;&nbsp;谁想要一遍又一遍地计算同一组价值?int&nbsp;func&nbsp;(int&nbsp;n)&nbsp;{&nbsp; &nbsp;&nbsp;static&nbsp;std::map<int,&nbsp;int>&nbsp;_cached; &nbsp;&nbsp;if&nbsp;(_cached.find&nbsp;(n)&nbsp;==&nbsp;_cached.end&nbsp;())&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;_cached[n]&nbsp;=&nbsp;n&nbsp;>&nbsp;0&nbsp;?&nbsp;n&nbsp;+&nbsp;func&nbsp;(n-1)&nbsp;:&nbsp;n; &nbsp;&nbsp;return&nbsp;_cached[n];}结果通过引入您的愚蠢优化,您只是打破了函数的每个用法,这些用法恰好位于需要常量表达式的上下文中。你从来没有承诺该函数的是使用常数表达式,没有constexpr就没有提供这样的承诺的方式。那么,我们为什么需要constexpr呢?constexpr的主要用途是声明意图。如果实体未标记为constexpr- 它从未打算用于常量表达式&nbsp;;&nbsp;即使它是,我们依靠编译器来诊断这样的上下文(因为它忽略了我们的意图)。

白衣非少年

拿std::numeric_limits<T>::max():无论出于何种原因,这是一种方法。constexpr这将是有益的。另一个例子:你想声明一个std::array与另一个数组一样大的C数组(或a&nbsp;)。目前这样做的方法是这样的:int&nbsp;x[10];int&nbsp;y[sizeof&nbsp;x&nbsp;/&nbsp;sizeof&nbsp;x[0]];但是能写的不是更好:int&nbsp;y[size_of(x)];谢谢你constexpr,你可以:template&nbsp;<typename&nbsp;T,&nbsp;size_t&nbsp;N>constexpr&nbsp;size_t&nbsp;size_of(T&nbsp;(&)[N])&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;N;}
随时随地看视频慕课网APP
我要回答