跟我学C++中级篇——编译期的条件选择

别再被网站识别成机器人了!用Python的undetected_chromedriver+Selenium实现无痕自动化 本文详细介绍了如何利用Python的undetected_chromedriver和Selenium实现无痕自动化,突破现代网站的反爬系统。通过修正浏览器指纹、模拟人类操作行为,并结合实战案例,帮助开发者构建难以被识别的自动化脚本,适用于电商监控等场景。 阅读详情

一、编译时的条件控制

在编译时的条件控制是非常经典的应用。除了开发才习以为常的宏控制编译环境等各种预处理指令,也包括C++新标准中提供的新的预处理器扩展。当然,这必然也包括各大处理器厂商等私自扩展的相关的预处理器指令等等。尤其是在C++20中,随着模块的出现,也提供了对模块进行条件编译的处理机制。
除了上述的条件控制外,对代码中逻辑的处理、分支的判断选择等等,C++中也提供了不少的方式来解决相关的问题。除了经常提到的SFINAE技术外,C++17、C++20中也都提供了控制的方式。
也就是说,在编译时的条件控制可以分为两大类:预编译器指令和逻辑条件控制。

二、预编译器指令

条件编译是预处理器指令中最多的应用场景。它分为以下几种情况:

  1. 基础条件指令
    常见的指令包括:"#if、#ifdef、#ifndef、#else、#elif、#endif"等等,看一个简单例子:

    // 防止头文件重复包含
    #ifndef __HEADER_H__
    #define __HEADER_H__
    ...
    #endif
    
    // 平台条件控制
    #ifdef _WIN32
    #include <windows.h>
    #else
    #include <unistd.h>
    #endif
    
  2. 编译厂商指令
    这种一般属于各编译器自行增加相关扩展指令,当这种编译器占主流时,自然也就成为了实际上的一种标准。如CC/Clang的#pragma once等。看例子:

    //和前面的防止头文件重复包含功能一致
    #pragma once 
    
  3. 逻辑判断指令
    它一般支持常量表达式用来进行条件控制,主要包括”#if defined()“等。比如常见的库中的代码:

    // 同时判断多个宏的组合条件
     #if defined(__cplusplus) && __cplusplus >= 201102L
     #define _STD_CPP11_ 1
     #endif
    
    

    #ifdef一般用于单个的条件判断,在这种情况下#if defined与其功能一致。但#if defined支持复杂的多条件组合使用

  4. C++新标准提供的指令
    随着C++标准的不断迭代发展,也不断推出相关的条件编译指令。如C++17中的“__has_include”以及在C++20中的模块条件编译控制。C++23中的“#elifdef和#elifndef ”。看下面的例子:

     #if __has_include(<tuple>)
     #include <tuple>
     #define HAS_STD_TUPLE 1
     #else
     // 引入boost中tuple
     #include <boost/tuple/tuple.hpp>
     #endif
    

预编译指令器的特点是语法简单、清晰,通用性好。而且支持多种平台语言。主要用于跨平台开发和头文件控制以及调试与日志管理。缺点是作用域的粒度太大,一般是文件级别,而且其和C++语法没有多大关系,多为宏指令,可读性和可维护性较差。
这种预编译的条件控制,细节有很多需要关注的情况。开发者需要在实际使用时,仔细应对,小心掉坑里去。

三、逻辑条件控制

在实际的开发中,有一种把一些计算或条件控制转移到编译期的发展方向。而这其中,特别是模板编程和元编程中,更是如此。毕竟它们可以整合在一起,实现更强大的功能。一般来说,在代码逻辑中实现条件控制有以下几种常见的机制:

  1. SFINAE
    在早期的条件分支控制中,除了一些简单的应用外,大多数需要SFINAE和std::enable_if,包括常见的模板特化、偏特化。特别是在处理一些条件的真或假进行编译选择时,std::enable_if就非常有用:
    //用来判断参数T的类型
     template <typename T, typename... Args, typename std::enable_if<std::is_integral<T>::value, int>::type * = nullptr>
     void invokeFunc(T t, Args... args) {
         ...
     }
    
    它一般用于约束和重载控制,用来确定生成或不生成某个函数或类。它和模板一起的是灵活的实现了各种需求。缺点就是太复杂了,可能很C++程序员整个生命周期都没有写过这类代码。
  2. if constexpr
    这个是C++17提供的一个条件编译控制的方式,它要求控制的表达式必须为常量表达式。其一般形式为:
    //c++17以后
    template <typename T>
    auto to_string(T t) {
        if constexpr(std::is_integral<T>::value) {
            return std::to_string(t);
        } else {
            return t;
        }
    }
    
    新的应用意味着语法的更明确、清晰,特别是对类型安全的控制。这是C++标准发展的一个重要方向。不过,缺点是它无法进行文件级别代码的处理(意味着无法代替预处理器指令)。同时,其粒度更低,导致无法控制模板的生成与否,只在生成的模板中控制分支
  3. Concepts
    概念是从C++20标准中提出的,它其实可以理解为对前面的SFINAE等机制的一种再次抽象和简化。当然,由于编译器跟进的问题,目前来看C++20的普及度还是不太够。看下面的代码:
    //函数限制
     template<typename T>
     concept func_ask = requires(T t)
     {
         t.must();
     };
    
    概念的优点当然是更安全、应用更明确清晰,缺点就是版本要求有点高,出现问题的定位仍然无法达到普通代码的水平,不易于处理

四、总结

C++应用的时间相对来说已经很长了,所以在历史的代码吧可以看到各种形式的条件处理机制。在实践中,当然推荐使用更先进的C++标准提供的方式,但不少的场景也离不开各种基础的编译器厂商的扩展指令。这就需要开发者根据实际情况,不断的推进在实践中的应用,根据不同的环境(特别是C++版本的不同)来综合使用各种编译条件控制。

FPGA以太网接口设计避坑指南:GMII与RGMII时序转换的三种实现方案对比 本文深入解析FPGA以太网接口设计中GMII与RGMII时序转换的三种实现方案,包括Xilinx官方IP核、手工原语逻辑和开源方案gmii_to_rgmii。通过对比分析各方案的优缺点和适用场景,为工程师提供技术选型指南,帮助避免常见设计陷阱,提升高速网络设备开发的效率和可靠性。 阅读详情

相关推荐

WSL 2 部署 Rocky Linux 9:从零到生产环境配置指南(2025版)

本文详细介绍了如何在WSL 2上部署Rocky Linux 9,从环境准备到生产环境配置的全流程指南。通过优化安装流程和系统配置,帮助开发者和运维工程师在Windows环境下高效运行企业级Linux系统,特别适合需要本地开发但部署到RHEL系服务器的项目。

weixin_28455801的博客 479

07C++之if条件选择

3.1.1 if 语句 作用:执行满足条件的语句 if语句的三种形式: 单行格式 if 语句 :if(条件){条件满足执行的语句} 多行格式 if 语句 :if(条件){条件满足执行的语句} else {条件满足执行的语句} 多条件的 if 语句 if (条件语句) { ​ else if() ​ { … ​ } } [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i4iZ4ivO-1646988215159)(C:/Users/dfghkl/AppData/R

请关注我,不定时分享个人在大厂嵌入式开发工作经验 856

【软考高级架构设计师】——2025年上半年软考真题(回忆版)

a)异构计算和算法优化b)资源抽象和容器控制c)安全和隔离(大致是这个意思)

小志的博客 4832

9.C++程序中的选择语句

选择语句一共分为两种:条件语句和开关语句其中条件语句叫if语句,常见的形式为:if ... else ...;再复杂一些为if... else if ... else ...;开关语句又叫switch语句,类型于开关的使用形式常见的有 switch (var) case : ... break;。选择语句可以实现多路分支,根据不同的条件进行选择或执行相应的代码或函数。

fly_binbin的专栏 1415

Seedance 2.5、HappyHorse 1.1与豆包Seed 2.1:一周内三大模型技术参数分析

音频生成延续原生音画同步架构,将文本、画面、音频统一序列建模,生成过程同步产出匹配口型的原声音频,支持中、英、日、韩、德、法、阿拉伯7种语言唇形对齐,无需二次调音。从行业趋势看,30秒直出、4K分辨率、7语种唇形同步正在成为视频生成的标配,编程Agent化和多模态理解正在成为语言模型的标配。技术狂奔的同时,监管在同步收紧。我理解这里的关键在于,视频生成模型的商业化落地不仅取决于生成质量,更取决于推理效率——生成一段15秒1080P视频需要多少秒、消耗多少算力,直接决定了模型的商用可行性。

lichunchuan1的博客 326

LabVIEW波形图表时间轴设置:三种方法实现横坐标显示日期时间

在数据采集与设备监控场景中,波形图表的横坐标默认显示采样点序号而非日期时间,这给工程师分析历史数据带来不便。理解时间标识(Timestamp)的本质——一个自1904年起算的双精度秒数,是解决问题的关键。时间轴设置既是显示格式问题,更是数据层与显示层的协同设计。通过属性节点动态生成刻度标签、将时间标识数组直接作为X轴数据、或使用波形数据(Waveform)类型绑定t0与dt,分别适用于固定点数显示、非等间隔事件记录和等间隔连续采样等不同需求。合理选择方案并注意缓冲区预分配与时间连续性处理,可让波形图表准确呈

weixin_33416697的博客 255

C++中的if选择语句的解析【适合初学者】

我们在人生中无时无刻不再选择,计算机中也是一样的。首先给大家说下if语句的作用,简单的说if语句就是一个做选择的语句。例如:桌上放着一个苹果 一个 香蕉你喜欢吃哪个呢? if else 语句解析 反正我喜欢吃苹果。  写到计算机中就是           前提条件:你喜欢吃那个                               if(喜欢吃苹果){

白璐 | 产品经理 5364

已过tiktok校招客户端,面经分享

面试的话, 一天面完3面, 效率很高, 三天之后就发了offer 字节邮件里面也说了不能泄露面试题, 那我就把我秋招参与美团,字节,腾讯,阿里面试被问到的全部问题总结着写出来了, 这其实是我每一轮面试完之后我都会总结哪里答对了, 哪里没有答对, 总结了一大堆问题出来. 答案未必正确, 我只是给自己写了个简单的一句话概括, 可能不够完善, 建议看官自行回答一下这些问题 二本非科班, 暑假在字节实习过, 不过不是tiktok部门, 因此秋招就没啥时间准备面试了, 只投了几个大厂, 顺便也在字节跨部门转正,

a1472750149的博客 1308

C++函数传递参数类型选择条件

使用引用参数的主要原因 1.能够修改调用函数中的数据对象 2.通过传递引用而不是整个数据对象,可以提高程序的运行速度 对于使用传递的值而不做修改的函数 1.如果数据对象很小,如内置数据类型或者小型结构,按值传递 2.如果数据对象是数组,则使用指针,并将指针声明为const的指针 3.如果数据对象是较大的结构,则使用const指针或者const引用,以提高程序的效率,节省复制结构所占用的时间复杂度和空间复杂度 4.如果数据对象是类对象的话,则使用const引用 对于修改调用函数中数据的函数 1.如果数据对象是

yoco的博客 683

FFMPEG音频开发: Linux下采集摄像头(使用V4L2框架)数据录制成MP4视频保存到本地

一、环境介绍 操作系统介绍:ubuntu 18.04 FFMPEG版本: 4.4.2 摄像头: USB摄像头、虚拟机挂载本机自带摄像头 二、FFMPEG与X264下载编译 X264下载地址: http://www.videolan.org/developers/x264.html FFMPEG下载地址:https://ffmpeg.org/download.html Yasm ...

8873

❤️爆肝十二万字《python从零到精通教程》,从零教你变大佬❤️(建议收藏)

文章目录强烈推荐系列教程,建议学起来!!一.pycharm下载安装二.python下载安装三.pycharm上配置python四.配置镜像源让你下载嗖嗖的快4.1pycharm内部配置4.2手动添加镜像源4.3永久配置镜像源五.插件安装(比如汉化?)5.1自动补码神器第一款5.2汉化pycharm5.3其它插件六.美女背景七.自定义脚本开头八、这个前言一定要看九、python入门十、python缩进十一、Python注释1.单行注释2.多行注释十二、Python 变量1.变量定义理解2. 变量名命名3. 分

全栈川川 26万+

C++条件判断

三种if 只有一种选择 if(表达式) 语句; 实例: #include <iostream> using namespace std; int main(void) { if(1<2) cout << "条件语句\n"; return 0; } 可以是多条语句 #include <iostream> using namespace std;...

小猪撸码 1843

Apollo EM Planner中路径-速度解耦优化的数学建模与仿真分析

摘要 Apollo EM Planner采用路径-速度解耦优化策略解决自动驾驶运动规划问题。该算法将时空轨迹规划分解为路径规划和速度规划两个子问题:首先在静态环境下生成几何最优路径,再优化沿路径的速度曲线。通过五次多项式表示路径和速度,构建包含平滑性、安全性、舒适性的多目标优化函数,并引入弹性模型处理动态障碍物约束。算法具有解耦优化、弹性适应、实时求解等特点,适用于高速公路、城市交叉口等多种场景。数学建模包括路径几何优化、速度动态优化和弹性势能函数,最终生成满足车辆动力学和环境约束的安全轨迹。

走向CTO的路上... 934

跟我学C++中级篇——编译期和运行时的性能处理分析

本文探讨了C++性能优化的两种主要方式:运行时优化和编译期优化。运行时优化包括多态处理、条件语句和表处理等方法,各有其优缺点,如多态处理编写复杂且性能较低,而表处理性能较好但对开发者要求较高。编译期优化通过C++新标准(如constexpr、模板元编程等)显著提升性能,如std::visit利用编译期多态、表机制和内联优化等特性。通过合理结合这两种优化方式,开发者可根据实际需求提升程序性能。

fpcc的专栏 1209

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

跟我学C++中级篇—编译期检查

对编译期的相关检查进行分析说明

fpcc的专栏 350

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

跟我学c++中级篇——c++17之constexpr if

对支持元编程的constexpr if进行分析说明,特别针对它的应用场景进行举例

fpcc的专栏 1846

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

跟我学c++中级篇——this指针

this是一个隐式的,默认的,自动的生成的一个指针,它通过编译器在编译行为期间进行控制而不需要开发者自己控制。可以将其理解为向开发者提供了一个可以更好的访问对象的接口。但在实际的开发中,很多开发者其实并没有很好的利用this指针。这就需要开发者们能充分认识到它的作用,发挥它的长处,形成一个好的开发习惯。

fpcc的专栏 990

跟我学c++中级篇——CRTP

对CRTP进行一个分析说明并举例应用

fpcc的专栏 1571

跟我学C++中级篇——返回值优化

在开发者编写代码的过程中,很多函数需要返回值的。如果只是简单的返回一个基础类型值,即使有一些浪费,这些浪费在整体的程序运行中其实影响还是相当小的。但当开发者自定义一些数据结构或者字符串等的返回时,就有可能出现多次拷贝的现象。这样的运行成本可能就相当大了。开发者在早期的编译期环境中,可能需要一些具体的技巧来处理这些返回值,但在越来越优秀的编译器加持下,返回值优化的手段从开发者不断的向编译期转移。这和前文(跟我学C++中级篇——临时对象)分析过的临时对象有着很大的联系,可一并参考学习分析。

fpcc的专栏 1577

跟我学C++中级篇——C++17中的std::void_t

std::void_t更好的是在模板和元编程中应用,这也是C++的一个发展的重点。毕竟泛型编程是每个语言都不能舍弃的情怀。所以对大多数程序员来说,std::void_t这个元函数属于一种应用非常少的情况。可以先了解一下,然后再真正遇到后再认真学习。在这篇普及的文章基础上,后面将对enable_if与std::void_t以及C++20中的std::integral‌进行一次系统的分析说明。这样,会让大家能从整体到细节上对模板和元编程中的相关用法有一个清晰的认识。

fpcc的专栏 1113

跟我学C++中级篇——if constexpr的应用

要关于对老的知识点的综合应用并不断的总结这种用法的可用之处,从而不断的推导出问题的解决办法。再通过这种解决办法可以看新的标准中是否有类似的更方便的方法,就可以更好的理解和认知一些技术点。可上层的给定的缓冲区内的数据类型确实是可变的,做为一个中间处理层,如何能够正确的引导程序自动适配准确的函数调用呢?本来这个非常简单,只要定义一个模板即可搞定,但这里偏偏有一个细节,是调用别人的库来实现写入。而这个库对不同的数据类型的写入,提供了N种不同的函数,这些函数只是名字和写入数据类型不同,其它都完全一样。

fpcc的专栏 990

跟我学C++中级篇——宏与constexpr

本文对比了C++中宏与constexpr的差异:宏仅进行文本替换,不进行类型检查且作用域不受限,适用于预处理和条件编译;constexpr则进行强类型检查,受作用域限制,支持编译期计算和复杂操作,调试更友好。虽然constexpr在大多数场景下更优,但宏在条件编译等特殊场景仍有优势。开发者应根据具体需求选择合适方案,权衡可维护性与功能需求。

fpcc的专栏 607

跟我学c++中级篇——注解

其实谈注解并没有多少太多的新奇的技术,在其它高级语言,特别是搞Java的同学中,这个太多了,现在几乎是普遍了。所以c++也在跟进,好的东西,其实是普遍受欢迎的,正如美是没有国界的。但c++固有的属性使其的发展不可能一下子就对注解之类的技术支持非常完美。但是只要开了头,后面就会越来越好。这里把这个注解拿出来,就是和反射在一起分析,让大家有一个更深刻的认识。对开发者来说简单的事情,可能对底层开发支持人员,就是一个新技术的应用。

fpcc的专栏 2853

跟我学C++中级篇——对类const关键字的分析说明

本文对比分析了C++中四个相似关键字const、constexpr、consteval和constinit的区别与应用场景。const用于运行时只读控制,constexpr支持编译期计算,consteval强制编译期求值函数,constinit确保静态变量的编译期初始化。文章通过示例代码展示了各关键字的具体用法,并指出应根据实际需求选择合适的关键字,同时考虑C++标准版本差异,以编写安全高效的代码。重点在于理解各关键字在编译期与运行期行为上的差异,以及它们在接口约束、编译期计算和初始化控制等场景下的适用性。

fpcc的专栏 781

跟我学C++中级篇——处理if条件分支语句

仍然是那句老话,“没有包打天下的技术”。想要灵活机变的综合应用各种技术解决实际问题,首先应该把基础打好,然后在实践中不断的应用总结。要善于发扬每种技术的长处,共同配合完成工作需要。所以搞技术学一些系统工程的知识也是相当有用处的。

fpcc的专栏 807

跟我学C++中级篇—C++17中的元编程逻辑操作

本文探讨了C++中的两类逻辑操作:运行时逻辑运算符(&&,||,!)和编译期元编程逻辑模板(std::conjunction,std::disjunction,std::negation)。前者用于运行时条件判断,后者在编译期进行类型检查与模板特化。文章详细介绍了三种元编程逻辑模板的用法,包括短路特性、辅助变量模板及其在SFINAE、类型约束等场景的应用。最后对比了两类逻辑操作的主要区别:应用时期不同(运行时vs编译期)、处理对象不同(值vs类型)以及实现机制差异。这些元编程工具为C++模板

fpcc的专栏 570
上一篇: 跟我学C++中级篇—编译期检查
下一篇: 算法和数据结构—动态规划法
fpcc
fpcc 新星创作者: C/C++技术领域 新星创作者: C/C++技术领域
博客等级 码龄22年 4041粉丝 1189原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值