news 2026/5/1 9:50:20

C++20中的预处理器宏——__VA_OPT__

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++20中的预处理器宏——__VA_OPT__

一、预处理器宏

预处理,Preprocessing,它是在正式编译前对源代码的一种文本层面的处理。主要包括宏展开、文件包含、条件编译以及注释等的处理。预处理器则是执行上面的预处理的一种工具,它会不涉及到语法或语义的操作。预处理器宏就是宏,与普通的宏没有本质区别。不过,它是用于进行预处理的。常见的预处理器宏有:#ifdef、#ifndef、#if等以及一些特定的功能宏如_FILE_ 和 __LINE__等。

二、_VA_OPT_ 和 _VA_ARGS_

在C语言的printf函数的实现中,大家都接触过__VA_ARGS__这个宏。这个宏在应用时有不少的小细节需要处理。其中,##__VA_ARGS__即_VA_ARGS__前面加上“##”可以处理当可变参数个数为0的时候,去掉前面多余的逗号(“,”),防止编译器报错。不过这个是GNU编译器的扩展,不属于标准库中的定义。可以参看看下面的示例代码。
而在C++20中为标准化统一,提供了“_VA_OPT
”这个宏用来处理空参数的问题。

#definePRINT(...)printf(__VA_ARGS__)#definePRINT_FMT(format,...)printf(format,__VA_ARGS__)#definePRINT_GNU(format,...)printf(format,##__VA_ARGS__)#definePRINT_CPP20(format,...)printf(format__VA_OPT__(,)__VA_ARGS__)intmain(){PRINT("test macro print\n");// PRINT_FMT("test macro print fmt\n");//空参数PRINT_FMT("test macro print fmt %d\n",100);PRINT_GNU("test macro print gnu\n");PRINT_GNU("test %s","my print\n");return0;}

三、分析说明

在上面也看到了__VA_ARGS__和__VA_OPT__的应用,__VA_OPT__应用的方法是:

__VA_OPT__(content)

对其来说当 __VA_ARGS__展开非零参数时,插入“展开的参数”;当_VA_ARGS_展开为空(0参数)时,忽略“,”或其它引起错误的情况。虽然__VA_OPT__是C++20标准提出的,但要使用还是需要看编译器的具体支持。其优势在于处理老式的可变参数宏处理时的漏洞,从而有条件的处理不同情况下的宏展开。特别是在与兼容C语言开发时,有着重要的作用。
不过,对于C++来说,如果不想使用__VA_OPT__可以使用变参模板和参数包展开等方式来来替代,这就看实际应用的具体情况了。

四、应用

宏的应用还是比较多的,只是不被推荐罢了。__VA_OPT__可以应用于条件处理、复杂数据的创建以及变参模板的支持等。看下面例程:

#include<iostream>#include<tuple>// tuple create#defineCREATE_TUPLE(...)std::make_tuple(__VA_OPT__(__VA_ARGS__))// create a named tuple#defineNAME_TUPLE(name,...)std::tuple_cat(std::make_tuple(name)__VA_OPT__(,std::make_tuple(__VA_ARGS__)))voidtest(){autoa=CREATE_TUPLE();autob=CREATE_TUPLE(1,'a',2.0,"abc");autoc=NAME_TUPLE("single");autod=NAME_TUPLE("two",1,1.1);autoe=NAME_TUPLE();std::cout<<std::tuple_size<decltype(a)>::value<<std::endl;std::cout<<std::tuple_size<decltype(b)>::value<<std::endl;std::cout<<std::tuple_size<decltype(c)>::value<<std::endl;std::cout<<std::tuple_size<decltype(d)>::value<<std::endl;std::cout<<std::tuple_size<decltype(e)>::value<<std::endl;std::cout<<std::get<1>(d)<<std::endl;std::cout<<std::get<0>(c)<<std::endl;}intmain(){test();return0;}

五、总结

虽然说宏的应用场景在不断的被压缩,但在某些场景下,还是无法替代的。特别是在预处理时,宏的应用非常广泛。所以C++20提供__VA_OPT__用于解决__VA_ARGS__的空参数的特殊场景也是可以理解的。这也可以明白为什么C/C++标准迭代的复杂性,历史既是功绩也是包袱。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 9:41:34

2026企业战略指南原圈科技AI市场分析指南赢在2026的企业竞争实操

原圈科技AI市场分析指南&#xff0c;旨在帮助企业应对2026年商业挑战。本文将通过三步教程&#xff0c;详解如何构建全域信息采集网络与多维度智能分析系统&#xff0c;并驱动自动化营销策略生成&#xff0c;将AI洞察转化为持续市场优势&#xff0c;实现从降本增效到战略引领的…

作者头像 李华
网站建设 2026/3/26 21:40:06

Python字典排序怎么按value排?这3种技巧你必须掌握

第一章&#xff1a;Python字典排序按value大小的核心概念在Python中&#xff0c;字典&#xff08;dict&#xff09;是一种无序的键值对集合。尽管从Python 3.7开始&#xff0c;字典保持了插入顺序&#xff0c;但其本身并不支持按值&#xff08;value&#xff09;自动排序。当需…

作者头像 李华
网站建设 2026/5/1 9:26:27

2026年最被低估的岗位:AI测试策略师,你准备好了吗?

行业裂变中的价值重构 2026年软件测试领域正经历颠覆性变革。ISTQB白皮书显示传统自动化脚本岗位需求同比下降52%&#xff0c;而AI测试策略师岗位年增长率达120%。这种断层式增长背后&#xff0c;是AI系统复杂度指数级提升带来的质量保障范式转移——测试正从“执行验证”转向…

作者头像 李华
网站建设 2026/5/1 6:56:24

【工业级爬虫架构设计】:集成OCR与模型识别绕过复杂验证码

第一章&#xff1a;工业级爬虫中的验证码挑战在构建工业级网络爬虫系统时&#xff0c;验证码&#xff08;CAPTCHA&#xff09;是绕不开的技术屏障。其设计初衷是区分人类用户与自动化程序&#xff0c;广泛应用于登录、注册、高频访问等场景&#xff0c;成为反爬策略的核心组成部…

作者头像 李华
网站建设 2026/5/1 7:48:31

服务器硬件全面解析:从CPU到网卡的运维必备知识

大家好&#xff0c;我是刘叨叨&#xff0c;一个致力于让碎片化技术系统性的运维人。 不懂硬件的运维&#xff0c;如同没有地图的探险家。本文将为你揭开服务器硬件的核心秘密&#xff0c;助你建立系统性的硬件知识体系。 第一章&#xff1a;CPU —— 服务器的"大脑" …

作者头像 李华
网站建设 2026/4/25 1:07:52

在Kubernetes中启用多节点NVLink的技术解析

在Kubernetes中为NVIDIA GB200 NVL72及后续平台启用多节点NVLink NVIDIA GB200 NVL72将AI基础设施推向新的极限&#xff0c;使得训练大语言模型和运行可扩展、低延迟的推理工作负载成为可能。无论是在本地还是在云端&#xff0c;Kubernetes在高效部署和扩展这些工作负载方面扮演…

作者头像 李华