constexpr关键字
起因
c++20为什么使用constexpr修饰find_if
#include
#include
int main() {
// OK constexpr std::array<char, 6> a {
'H', 'e', 'l', 'l', 'o' }; // Failures: // * std::find is not constexpr constexpr auto it = std::find(a.rbegin(), a.rend(), 'H'); }
c++20后添加constexpr对之前的代码会有影响吗(会不会导致之前的代码失效)?
按照P0202R3的介绍不会有任何影响,单纯的库扩展。
- 让编译期计算达到类型安全
- 一般来说,通过将计算移至编译期来提高效率
- 支持嵌入式系统编程(尤其是 ROM)
- 直接支持元编程
- 让编译期编程与“普通编程”非常相似
对于Constant-expression functions值得注意的一点描述有:一个constexpr function是可能被使用non-constant expressions调用的,这个时候这个函数调用就不需要编译器计算。
constexpr int func(int x) {
return x; } int main() {
constexpr int i = 1; func(i); // 编译期计算 int j = 2; func(j); // 运行期计算 return 0; }
// square可以解决宏函数的一些问题:类型不安全问题 constexpr int square(int x) {
return x * x; } // fine constexpr long long_max() {
return ; } // fine constexpr int abs(int x) {
return x < 0 ? -x : x; } // fine constexpr void f(int x) // error: return type is void {
/* ... */ } constexpr int next(int x) {
return ++x; } // error: use of increment constexpr int g(int n) // error: body not just ‘‘return expr’’ {
int r = n; while (--n > 1) r *= n; return r; } constexpr int twice(int x); enum {
bufsz = twice(256) }; // error: twice() isn’t (yet) defined constexpr int fac(int x) {
return x > 2 ? x * fac(x - 1) : 1; } // error: fac() not defined before use
#include
constexpr int test(int n) {
int k = n; // 支持局部变量 k++; return k; } int main() {
constexpr int i = 11; int k = test(i); // 编译期计算 int j = 22; int m = test(j); // 运行期计算 }
Bjarne Stroustrup在HOPL4 论文的5.5章节中写道:
这种放松简化了许多 constexpr 函数并使许多 C++ 程序员感到高兴。他们不满地发现,以前在编译时只能对算法的纯函数表达式进行求值。特别是,他们希望使用循环来避免递归。就更长期来看,这释放出了要在 C++17 和 C++20中进一步放松限制的需求。为了说明潜在的编译期求值的能力,我已经指出 constexpr thread 也是可能的,尽管我并不急于对此进行提案。
- consteval——保证在编译期进行求值的 constexpr 函数 [Smith et al. 2018a]
- constinit——保证在编译期初始化的声明修饰符 [Fiselier 2019]
- 允许在 constexpr 函数中使用成对的 new 和 delete [Dimov et al. 2019]
- constexpr string 和 constexpr vector [Dionne 2018]
- 使用 virtual 函数 [Dimov and Vassilev 2018]
- 使用 unions、异常、dynamic_cast 和 typeid [Dionne and Vandevoorde 2018]
- 使用用户定义类型作为值模板参数——最终允许在任何可以用内置类型的地方使用用户定义类型 [Maurer 2012]
- is_constant_evaluated() 谓词——使库实现者能够在优化代码时大大减少平台相关的内部函数的使用 [Smith et al. 2018b]
拿constval来讲,针对上面的例子
#include
constval int test(int n) {
int k = n; // 支持局部变量 k++; return k; } int main() {
constexpr int i = 11; int k = test(i); // 编译期计算 int j = 22; int m = test(j); // 会导致编译失败 }
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/214930.html原文链接:https://javaforall.net
