在我看来,拥有一个“总是返回5的函数”是破坏或冲淡了“调用函数”的含义。这肯定是有原因的,或者需要这种功能,否则它就不会出现在C++11中,为什么会出现呢?
// preprocessor.
#define MEANING_OF_LIFE 42
// constants:
const int MeaningOfLife = 42;
// constexpr-function:
constexpr int MeaningOfLife () { return 42; }在我看来,如果我写了一个返回文字值的函数,然后我进行了代码审查,有人会告诉我,我应该声明一个常量值,而不是写return 5。
发布于 2011-01-20 22:27:38
假设它做了一些更复杂的事情。
constexpr int MeaningOfLife ( int a, int b ) { return a * b; }
const int meaningOfLife = MeaningOfLife( 6, 7 );现在,您有了可以计算为常量的东西,同时保持良好的可读性,并允许比仅将常量设置为数字稍微复杂一些的处理。
它基本上为可维护性提供了很好的帮助,因为您正在做的事情变得越来越明显。以max( a, b )为例:
template< typename Type > constexpr Type max( Type a, Type b ) { return a < b ? b : a; }这是一个非常简单的选择,但它确实意味着如果您使用常量值调用max,它将在编译时显式计算,而不是在运行时计算。
另一个很好的例子是DegreesToRadians函数。每个人都发现度比弧度更容易读懂。虽然您可能知道180度是弧度的3.14159265 (Pi),但它写得更清楚,如下所示:
const float oneeighty = DegreesToRadians( 180.0f );这里有很多好的信息:
http://en.cppreference.com/w/cpp/language/constexpr
发布于 2015-03-03 07:51:17
引言
引入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 -它从来没有打算在常量表达式中使用;即使它被标记了,我们也要依靠编译器来诊断这样的上下文(因为它忽略了我们的意图)。
发布于 2011-01-20 22:32:20
以std::numeric_limits<T>::max()为例:无论出于什么原因,这都是一种方法。在这里,constexpr将是有益的。
另一个示例:您希望声明一个与另一个数组一样大的C数组(或std::array)。目前的方法是这样的:
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;
}https://stackoverflow.com/questions/4748083
复制相似问题