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
- 它从未打算用于常量表达式 ; 即使它是,我们依靠编译器来诊断这样的上下文(因为它忽略了我们的意图)。
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;}
- 3 回答
- 0 关注
- 1108 浏览
添加回答
举报