c++23中的新功能之八隔离编译期与运行期

news/2025/2/19 8:12:19/

一、介绍

前面介绍过if constexpr这后头就跟上了if consteval,说白了,就是前有车,后面就得跟上辙,成套成系列的。无论是在模板编程还是在元编程中,都会有编译期处理和运行期处理的一些需求,这些需求是产生这些技术的根本的要求,看来c++在这条路上想一条路跑到黑了。
在c++20中,介绍过consteval和std::is_constant_evaluated()这两个特性,前者确定在编译期的展开执行,后者是提供一个判断是否在编译期执行的函数。比如在前面学习可以知道constexpr函数既可以在编译期也可以在运行期执行,那么这个判断函数就可以派上用场了。

二、if consteval的用法和实例

为了能更好的展示if consteval的用法,先从一个小的例程开始:

#include <iostream>
#include <array>
#include <span>
constexpr int Add(std::span<const int> sp)
{if (std::is_constant_evaluated()){int r = 0;for (auto au : sp) { r += au * au; }return r;}else{__asm {mov al, 2};}
}
int main()
{std::array<int, 3> arr = {1,2,3};Add(std::span{arr});
}

这时候儿会不会想到可以考虑一下if constexpr这个特性,也就是说,用提到的这个方法来做一些判断:


#include <iostream>
#include <array>
#include <span>consteval int Compiler(std::span<const int> sp)
{int r = 0;for (auto au : sp) { r += au * au; }return r;
}
constexpr int Add(std::span<const int> sp)
{//注意下面两行if  (std::is_constant_evaluated())//if constexpr (std::is_constant_evaluated()){return Compiler(sp);}else{__asm {mov al, 2};}
}
int main()
{std::array<int, 3> arr = {1,2,3};Add(std::span{arr});
}

恭喜,你收获了一个错误,而且这个错误有点莫名其妙(" 对即时函数的调用不是常量表达式")。原因在于开发者想当然的认为判断一下然后再决定是运行期还是编译期,可问题是,你的判断很可能已经在运行期了,这和你已经上大学了,再让你填写高考志愿,有点过分了啊。
那么有些人会马上想到if constexpr,这个可是好东西啊,正如上面的注释掉的那行,然后解开,把上面的那行代码注释。可仔细一想,这个constexpr if是确定性的在编译期执行,那么你再加一层判断又有什么用处呢?所以就得增加一个方法来解决这个问题,于是乎今天要讲的if consteval出现了。
在c++23中就可以使用下面的代码(下面的代码使用GNU c++编译器,注意和VC不同):


#include <iostream>
#include <array>
#include <vector>
#include <span>
#include <limits>consteval  int Compiler(std::span<const int> sp)
{int r = 0;for (auto au : sp) { r += au * au; }return r;
}constexpr int Add(std::span<const int> sp)
{if consteval{return Compiler(sp);}else{__asm__ ("mov 2,%al");//AT&T}
}
int main()
{std::vector<int> vec{1,2,3};std::span sp{vec};Add(sp);
}

可惜的是,VC最新的编译器支持版本也编译不过去。不过在cppreferece上可以运行,这个是最新的,不过注意VC与GNU的不同。
再看一个cppreference.com上的例子:

#include <cmath>
#include <cstdint>
#include <cstring>
#include <iostream>constexpr bool is_constant_evaluated() noexcept
{if consteval { return true; } else { return false; }
}constexpr bool is_runtime_evaluated() noexcept
{if not consteval { return true; } else { return false; }
}consteval std::uint64_t ipow_ct(std::uint64_t base, std::uint8_t exp)
{if (!base) return base;std::uint64_t res{1};while (exp){if (exp & 1) res * = base;exp /= 2;base * = base;}return res;
}constexpr std::uint64_t ipow(std::uint64_t base, std::uint8_t exp)
{if consteval // use a compile-time friendly algorithm{return ipow_ct(base, exp);}else // use runtime evaluation{return std::pow(base, exp);}
}int main(int, const char* argv[])
{static_assert(ipow(0,10) == 0 && ipow(2,10) == 1024);std::cout << ipow(std::strlen(argv[0]), 3) << '\n';
}

这个在网站上就可以运行。

三、、总结

学习新的标准的最大痛点在于编译器的支持。这个目前没有太好的方法,可以在一些网站上运行,也可以自己下载最新版本的编译来运行,这个就看个人的喜好。新的东西意味着不太稳定,所以还是先掌握趋势,对于在实际工程中,不要急于应用。
大胆学习,谨慎应用。


http://www.ppmy.cn/news/435730.html

相关文章

tolua源码分析(八)lua扩展继承C#类

tolua源码分析&#xff08;八&#xff09;lua扩展继承C#类 上一节我们阐述了lua调用带out参数的C#函数机制&#xff0c;本节我们来看下lua层是如何扩展C#类的。这次的例子在example 17&#xff0c;主要都是lua代码&#xff1a; LuaTransform { } …

卧槽!这网站也太全了吧!!!学习、设计、开发、资源下载等各类高质量网站推荐【建议收藏】

有了这些网站&#xff0c;开发&#xff0c;设计速度提升了n倍&#xff0c;效率提升了&#xff0c;薪资自然就涨涨涨 声明&#xff1a; 本网址从网上搜寻而来&#xff0c;有的网址在使用时如出现过期情况&#xff0c;请反馈欢迎有好的网站的私聊进行分享本帖会不定期更新&#…

基于知识图谱的电影推荐系统——Neo4jPython

文章目录 1. 数据解下载与配置2. 将处理好的数据导入数据库中3. 执行项目 1. 数据解下载与配置 选择TMDB电影数据集&#xff0c;Netflix Prize 数据集下载。 也可直接从这里下载&#xff1a;链接: https://pan.baidu.com/s/1l6wjwcUzy5G_dIlVDbCkpw 提取码: pkq6 。 执行prep…

幻灯片转换为一页多张讲义打印格式

在实际学习过程中&#xff0c; 我们有时会需要将PPT格式的幻灯片打印出来&#xff0c;为了节省纸张&#xff0c;可以在一页上打印多页幻灯片。但直接在WPS或powerpoint设置打印格式&#xff0c;会使得白边过多&#xff0c;打印效果不够紧凑。为此&#xff0c;本篇博文将利用WPS…

单张PPT转成单张PDF的PDF文件怎么设置打印出一页纸有6页PPT

感谢天津大学李森的技术帮助atomer 常见的PPT可以在打印的时候设置的时候设置每页纸打印6页PPT(由于下面电脑没有连接打印机&#xff0c;所以没法设置打印页边距&#xff0c;导致现在的页边距比较宽&#xff0c;PPT页面和纸张大小不一致) 但是举办方为了保护用户的版权&#xf…

php针式打印机打多张,ppt打印怎么一页打多个

ppt打印一页多个的方法&#xff1a;首先在电脑上找到需要打印的PPT&#xff1b;然后找到点击“文件”&#xff0c;并在出现的信息中点击“打印”&#xff1b;接着找到“打印内容”&#xff0c;点击一下&#xff0c;并在出现的信息中选择“讲义”&#xff1b;最后点击选择数量即…

如何在PPT中实现多张图片叠加在一起,点击消失一张出来下一张的效果

原文&#xff1a;http://blog.sina.com.cn/s/blog_4fc125320100p9ub.html 这两天在帮忙修改一个PPT的课件&#xff0c;主要内容是让学生学习关于职业的单词&#xff0c;在PPT里的有一个效果是在同一张幻灯片里&#xff0c;点击出来第一张图片&#xff0c;学习完之后&#xff0…

PPT打印处理 深色背景/白色字体转换 + 多分页占满

目录 1. 初始样式 2. 设置背景 3. 设置分页 4. 设置纯黑白&#xff0c;使文字打印出来 1. 初始样式 背景为深色&#xff0c;而字体为白色&#xff0c;但打印的时候希望整体为白色&#xff0c;否则打印机消耗太大。 2. 设置背景 首先如下图将背景设置为白色&#xff0c;如…