当前位置: 首页 > news >正文

C++ -- 型号比对和constexpr

1、std::is_same

std::is_same是 C++ 标准库<type_traits>头文件中提供的一个‌类型特征(Type Trait)‌模板类。它的主要作用是在‌编译期‌严格判断两个类型是否完全相同。

std::is_same是一个模板结构体,接受两个类型参数T1T2。它包含一个静态成员常量value

  • 如果T1T2是‌完全相同‌的类型,std::is_same<T1, T2>::valuetrue
  • 否则,为false

从 ‌C++17‌ 开始,引入了变量模板std::is_same_v,它是::value的简写形式,使用更加便捷。

#include <iostream> #include <type_traits> int main() { // C++11/14 写法 std::cout << std::boolalpha; std::cout << "int vs int: " << std::is_same<int, int>::value << std::endl; // true std::cout << "int vs double: " << std::is_same<int, double>::value << std::endl; // false // C++17 及以后推荐写法 (更简洁) std::cout << "int vs int (v): " << std::is_same_v<int, int> << std::endl; // true return 0; }

std::is_same进行的是‌字面意义上的严格类型比较‌,它‌不会‌进行任何隐式类型转换或类型归一化。以下情况均被视为‌不同‌类型:

// 这些都会返回 false std::is_same_v<int, const int>; // false std::is_same_v<int, int&>; // false std::is_same_v<char, signed char>; // false (注意这点,很多初学者会误以为为 true)

2、if constexpr

if constexpr是 C++17 引入的一项关键特性,用于在‌编译期‌进行条件判断。它允许编译器根据常量表达式的值,选择性地实例化代码分支。

与传统的运行时if语句或预处理器宏(如#ifdef)不同,if constexpr的核心优势在于:‌未被选中的分支会被完全丢弃,不参与编译,甚至不会进行语法检查。

if constexpr (condition) { // 当 condition 为 true 时,编译此分支 } else { // 当 condition 为 false 时,编译此分支(可选) }
  • condition‌:必须是一个‌编译期常量表达式‌(constexpr expression),例如std::is_integral_v<T>、字面量比较或constexpr变量。
  • 行为‌:
    • 如果条件为true,编译器只实例化if块内的代码。
    • 如果条件为false,编译器只实例化else块内的代码(如果有)。
    • 被丢弃的分支被视为“不存在”‌,即使其中包含语法错误或针对当前类型非法的操作(如调用不存在的成员函数),也不会导致编译错误。
template<typename T> void process(T val) { if constexpr (std::is_same_v<T, int>) { std::cout << "处理整数: " << val << std::endl; } else if constexpr (std::is_same_v<T, double>) { std::cout << "处理浮点数: " << val << std::endl; } else { std::cout << "处理其他类型" << std::endl; } }

使用std::enable_if控制函数重载,这是 SFINAE 最经典的应用。通过std::enable_if,可以根据类型特征决定是否让某个模板参与重载决议。

SFINAE‌(Substitution Failure Is Not An Error,替换失败并非错误)机制的技术手段。

#include <iostream> #include <type_traits> // 只有当 T 是整数类型时,此函数才参与重载 template<typename T> typename std::enable_if<std::is_integral<T>::value, void>::type process(T value) { std::cout << "Processing integer: " << value << std::endl; } // 只有当 T 是浮点类型时,此函数才参与重载 template<typename T> typename std::enable_if<std::is_floating_point<T>::value, void>::type process(T value) { std::cout << "Processing float: " << value << std::endl; } int main() { process(42); // 调用整数版本 process(3.14); // 调用浮点版本 // process("hello"); // 编译错误:没有匹配的重载,因为 string 既不是 integral 也不是 floating_point return 0; }

typename std::enable_if<std::is_integral<T>::value, void>::type

它的核心作用是:‌只有当模板参数T是整数类型时,这个表达式才代表一个有效的类型(即void);如果T不是整数类型,该表达式会导致编译时的“替换失败”,从而将当前的函数或类特化从重载候选集中静默移除。

A.std::is_integral<T>::value
  • 含义‌:这是一个类型特征(Type Trait),用于判断类型T是否为‌整数类型‌(如int,char,long,bool等)。
  • 结果‌它是一个编译期常量布尔值:
    • 如果T是整数类型,结果为true
    • 如果T不是整数类型(如float,double,class等),结果为false
B.std::enable_if<Condition, Type>
  • 定义‌:std::enable_if是一个模板结构体,定义在<type_traits>头文件中。它接受两个模板参数:
    1. B(Condition):一个布尔值。
    2. T(Type):一个类型,默认值为void
  • 行为逻辑‌:
    • 如果Btrue‌:std::enable_if内部会定义一个公共成员类型别名type,其等价于第二个参数T
    • 如果Bfalse‌:std::enable_if内部‌没有‌定义任何名为type的成员。
C.::type
  • 含义‌:尝试访问std::enable_if结构体中的成员类型type
  • 关键点‌:
    • std::is_integral<T>::valuetrue时,::type存在,且等价于void(因为第二个参数传的是void)。
    • std::is_integral<T>::valuefalse时,::type不存在‌。
D.typename
  • 含义‌:告诉编译器,后面的...::type是一个‌类型名称‌,而不是静态成员变量或其他东西。因为在模板中,依赖型名称(dependent name)默认不被视为类型,必须显式加上typename
情况 1:调用myFunction(10),此时T推导为int
  1. std::is_integral<int>::valuetrue
  2. std::enable_if<true, void>被实例化。
  3. 因为条件为真,std::enable_if内部定义了typedef void type;
  4. typename ... ::type成功解析为void
  5. 函数签名变为void myFunction(int t)
  6. 结果‌:该函数是一个合法的重载候选,参与编译。
http://www.gsyq.cn/news/1332254.html

相关文章:

  • 用PyTorch复现ICCV 2023的蛇形卷积(DSCNet),搞定血管分割的细长结构难题
  • Cortex-M7内存架构与嵌入式系统优化实践
  • C#批量打印防卡死:用Win32 API实时监控打印机队列任务数(附完整代码)
  • Vidupe智能视频去重工具:3步高效清理重复视频的实用指南
  • Gitee项目管理为什么成为中国团队首选:本土化、安全合规与DevOps全链路的三重优势
  • 【AI摄影权威白皮书】:基于1276组A/B测试数据,验证--s 100~200区间对细节还原率的影响(附参数衰减曲线图)
  • 工作服厂家选购指南:如何选到靠谱的定制厂家 - 资讯速览
  • 从‘照亮’到‘出氛围’:手把手教你用Unity URP打造有质感的室内灯光(含Bloom/ACES配置)
  • STM32硬件设计实战:从数据手册到PCB的电源架构深度解析
  • 学校机房U盘病毒杀不完?深入分析Waveedit进程与注册表启动项的清除方法
  • 2026年扬州婚纱摄影值得选,不踩雷合集 - 品牌企业推荐师(官方)
  • [网络工程师]-路由配置-NAT策略与多出口场景实战
  • GEE实战:Landsat 8 TOA和SR数据去云处理,保姆级代码对比与避坑指南
  • 2026年怎么选靠谱滚筒厂家?优耐德科技定制方案解决输送痛点 - 资讯速览
  • 靠谱的窄边框工艺设备哪个好 - 品牌企业推荐师(官方)
  • 首達時間處的路徑交疊
  • 3分钟搞定GitHub加速:免费浏览器插件终极指南
  • 轻量级YOLOv5n赋能无人机智能巡查,构建乡村罂粟花非法种植实时检测预警系统
  • 智能汽车每天产生4TB数据,OTA固件升级怎么防被篡改?车联网密钥管理实操
  • 初创公司如何利用Taotoken管理多模型API成本与用量
  • 别再死记硬背参数了!Halcon形状匹配(create_shape_model)核心参数保姆级解读
  • 用PyTorch和CNN搞定MNIST手写数字识别:从数据加载到模型部署的完整实战指南
  • 2026年5月最新 市政污水在线余氯监测仪国产十大口碑品牌排行榜 - 水质仪表品牌排行榜
  • 专业的AIGC应用工程师值得信赖的公司 - 品牌企业推荐师(官方)
  • 内幕揭秘:6款免费AI论文工具隐藏技巧,导师不会告诉你的高阶玩法 - 麟书学长
  • 实战解析:HAL库下ADC常规与注入模式在电机控制中的协同采样策略
  • AI写作辅助平台8款一键生成论文工具势力榜,毕业护航利器!
  • 学术查证慢如龟速?用Perplexity 10秒定位《费曼物理学讲义》原始公式,附7个不可替代的提示词模板
  • 告别盲目配置:用STM32CubeMX玩转GPIO输入输出,详解HAL库与LL库代码差异与选择
  • 在曙光超算上跑PyTorch?这份保姆级Slurm避坑指南请收好(含完整脚本模板)