【Effective Modern C++】第三章 转向现代C++:10. 优先选用限域枚举,而非不限域枚举

使用限域enum来减少命名空间污染

通用规则:如果在一对大括号里声明一个名字,则该名字的可见性限定在括号括起来的作用域内。

但这个规则不适用于 C++98 风格的枚举类型中定义的枚举变量:枚举变量的属于包含着这个枚举类型的作用域,此作用域内不能有其他实体取相同的名字。

enum Color { black, white, red }; //black, white, red在Color所在的作用域 auto white = false; //错误! white早已在这个作用域中声明

枚举量的名字泄露到枚举类型所在作用域的现象被称为:不限范围的枚举类型(未限域enum)。

在 C++11 中,限定作用域的枚举类型(枚举类 / 限域enum)不会以这样的方式泄露名字:

enum class Color { black, white, red }; //black, white, red限制在Color域内 auto white = false; //没问题,域内没有其他“white” Color c = white; //错误,域中没有枚举名叫white Color c = Color::white; //没问题 auto c = Color::white; //也没问题(也符合5的建议)

限域枚举的枚举量是强类型的

强类型:语言会对类型兼容性做严格检查,禁止隐式的、不安全的类型转换,每个值都有明确且固定的类型,类型错误会被尽可能早地捕获(编译器 / 运行期)。

不限域枚举类型的枚举量可以隐式转换为整数类型(并能够从此处进一步转换到浮点类型),导致语义扭曲的代码合法:

enum Color { black, white, red }; //未限域enum std::vector<std::size_t>primeFactors(std::size_t x); //func返回x的质因子 Color c = red; if (c < 14.5) { // Color与double比较 (!) auto factors = primeFactors(c); // 向std::size_t参数传递Color (!) … }

从限定作用域的枚举类型到任何其他类型都不存在隐式转换路径,类型安全更优:

enum class Color { black, white, red }; //Color现在是限域enum Color c = Color::red; if (c < 14.5) { //错误!不能比较Color和double auto factors = primeFactors(c); //错误!不能向std::size_t参数传Color … } // 仅显式强制转换才允许(可控的类型转换) if (static_cast<double>(c) < 14.5) { auto factors = primeFactors(static_cast<std::size_t>(c)); }

限定作用域的枚举类型可以进行前置声明

前置声明的核心前提是编译器能确定枚举的底层类型(内存大小)

enum Color; // 错误!未限域enum无默认底层类型,编译器无法推断内存大小 enum class Color; // 没问题!限域enum默认底层类型为int,内存大小确定

底层类型与前置声明的完整规则

  1. 所有enum的底层类型是编译器为优化内存选择的整型(需覆盖所有枚举值的最小类型);
  2. 限域enum:默认底层类型为int(也可显式指定),因此总能直接前置声明
enum class Status; // 默认int,合法 enum class Status: std::uint32_t; // 显式指定底层类型,合法
  1. 未限域enum:无默认底层类型,仅显式指定底层类型时才能前置声明
enum Color: std::uint8_t; // 显式指定底层类型,合法
  1. 两者均可在定义时显式指定底层类型:
enum class Status: std::uint32_t { good = 0, failed = 1 }; enum Color: std::uint8_t { black, white, red };

未限域枚举的唯一实用场景:简化std::tuple字段访问

限域enum虽类型安全,但访问std::tuple字段时因无隐式转换,代码冗长;未限域enum可利用 “隐式转换为std::size_t” 简化模板实参传递:

// 定义tuple类型(存储用户名、邮箱、声望值) using UserInfo = std::tuple<std::string, std::string, std::size_t>; // 未限域enum:简洁访问tuple字段(依赖隐式转换为std::size_t) enum UserInfoFields { uiName, uiEmail, uiReputation }; UserInfo uInfo; auto val = std::get<uiEmail>(uInfo); // 直接用枚举成员作为模板实参 // 限域enum:无隐式转换,代码冗长 enum class UserInfoFields { uiName, uiEmail, uiReputation }; auto val = std::get<static_cast<std::size_t>(UserInfoFields::uiEmail)>(uInfo);

限域枚举访问 tuple 的优化方案:toUType constexpr 函数模板

为兼顾限域enum的类型安全与tuple访问的简洁性,可实现编译期生效toUType函数模板(转换枚举值为其底层类型):

C++11 版本:

template<typename E> constexpr typename std::underlying_type<E>::type toUType(E enumerator) noexcept { return static_cast<typename std::underlying_type<E>::type>(enumerator); }

C++14 简化版本(更简洁):

template<typename E> constexpr auto toUType(E enumerator) noexcept { return static_cast<std::underlying_type_t<E>>(enumerator); }

调用方式(兼顾安全与简洁):

auto val = std::get<toUType(UserInfoFields::uiEmail)>(uInfo);

总结

  • C++98风格的枚举类型称为不限范围的枚举类型。
  • 限定作用域的枚举类型仅在枚举类型内可见。它们只能通过cast强制类型转换以转换至其他类型。
  • 限定作用域的枚举类型和不限范围的枚举类型都支持底层类型指定。限域的枚举类型的默认底层类型是int,而不限域的枚举类型没有默认底层类型。
  • 限定作用域的枚举类型总是可以进行前置声明,而不限域的枚举类型却只有在指定了默认底层类型的前提下才可以进行前置声明。

原著在线阅读地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1214424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业IT管理:如何合理设置文件夹权限?

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个企业级文件夹权限管理工具&#xff0c;功能包括&#xff1a;1) 可视化权限树 2) 批量权限修改 3) 权限继承分析 4) 权限变更历史记录 5) 异常权限检测。要求支持Active Di…

Python应用日志管理:自动化按日期分割日志的完整指南

Python 应用日志管理&#xff1a;自动化按日期分割日志的完整指南&#xff08;2025-2026 实用版&#xff09; 目前生产环境中按日期&#xff08;或按大小日期&#xff09;分割日志仍然是最主流、最可靠的做法。下面给出从简单到生产可用的完整方案梯度。 方案对比&#xff08…

Docker Desktop虚拟化不支持导致启动失败解决方案

【Docker Desktop 启动失败】“虚拟化不支持” / “Virtualization is not supported” 完整血泪解决方案&#xff08;2026 年最新版&#xff09; Docker Desktop&#xff08;Windows / Mac&#xff09;启动时报“虚拟化不支持”或“Virtualization support not detected / no…

《简易制作 Linux Shell:详细分析原理、设计与实践》

《简易制作 Linux Shell&#xff1a;详细分析原理、设计与实践》 Linux Shell 是用户与内核互动的桥梁&#xff0c;负责命令解析、执行和环境管理。自己做一个简易 Shell&#xff0c;能让你深刻理解操作系统原理&#xff08;如进程管理、I/O 重定向、管道&#xff09;。 这个指…

2026年无机磨石厂商如何选?这份口碑榜单值得参考

一、行业背景与市场趋势 近年来,随着绿色建筑理念的深入和人们对健康环保生活空间需求的提升,地面装饰材料市场正经历一场深刻的变革。传统有机类地坪材料因其在环保性、耐久性及防火性能上的局限,逐渐无法满足高端…

2026年新疆地区石英砂供应厂家实力推荐榜

一、摘要 随着新疆地区基础设施建设的持续推进、光伏新能源产业的蓬勃发展以及环保水处理需求的日益增长,作为重要工业原料的石英砂,其市场需求在2026年依然保持强劲态势。新疆本地依托丰富的石英石矿产资源,涌现出…

8 万个智能体 Skills 怎么选?skills.sh 排行榜帮你避开所有坑

大家好&#xff0c;我是玄姐。如今 Agent Skills 的数量早已迎来爆发式增长&#xff0c;据全网最全的聚合平台 SkillsMP 统计&#xff0c;目前已收录超 8 万个 Skills。这类工具无疑为 AI 智能体开发提供了强大助力&#xff0c;但面对海量选择&#xff0c;"哪些才真正好用…

用AI快速验证你的AO3同人小说创意

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个AO3创意验证工具&#xff0c;用户输入简短创意描述&#xff08;如哈利波特与马尔福的校园恋爱故事&#xff09;&#xff0c;AI在1分钟内生成3个不同版本的故事开头&#x…

NumPy零基础入门:AI助手教你玩转科学计算

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 制作一个面向初学者的NumPy交互式教程&#xff0c;包含以下内容&#xff1a;1) 创建各种类型的数组&#xff08;零数组、单位矩阵、随机数组等&#xff09;&#xff1b;2) 基本索引…

小白必看:HOSTS文件修改图文详解(含视频)

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 制作一个交互式HOSTS学习应用&#xff0c;包含&#xff1a;1. 动画演示工作原理 2. 分步骤向导式修改指导 3. 常见错误模拟演示 4. 自测练习题 5. 应急恢复指南。要求使用HTML5开发…

AI如何优化PING命令:智能网络诊断新方案

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个AI增强版PING工具&#xff0c;要求&#xff1a;1. 支持多目标并行PING测试 2. 自动分析延迟数据生成可视化图表 3. 根据历史数据预测网络波动 4. 提供故障诊断建议 5. 可保…

AI一键搞定TOMCAT安装:告别繁琐配置

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 请生成一个完整的TOMCAT 9.0安装脚本&#xff0c;要求包含以下功能&#xff1a;1.自动检测系统环境&#xff08;Linux/Windows&#xff09;并适配对应安装包 2.配置JAVA_HOME环境变…

【开题答辩全过程】以 金太阳宠物用品网站为例,包含答辩的问题和答案

个人简介 一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等 开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。 感谢大家…

【开题答辩全过程】以 基于web的高校水电费管理系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

为初学者详细解析AXURE10的授权原理,提供官方和替代获取渠道,避免常见激活陷阱。

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 制作一个AXURE10授权知识问答应用&#xff0c;包含&#xff1a;1) 授权机制动画演示 2) 正版购买引导 3) 常见问题解答 4) 风险提示模块。使用HTML5开发响应式网页&#xff0c;加入…

AI如何帮你快速掌握XP.1024新版本特性

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 使用快马平台的AI功能&#xff0c;分析XP.1024最新版本的更新日志&#xff0c;提取关键特性并生成对应的代码示例。要求包括&#xff1a;1. 列出所有新增功能&#xff1b;2. 对比旧…

学霸同款2026 9款一键生成论文工具测评:本科生毕业论文必备清单

学霸同款2026 9款一键生成论文工具测评&#xff1a;本科生毕业论文必备清单 2026年学术写作工具测评&#xff1a;为何需要这份榜单&#xff1f; 随着人工智能技术的不断进步&#xff0c;越来越多的本科生开始依赖AI工具来辅助毕业论文的撰写。然而&#xff0c;面对市场上琳琅满…

2026年无机纤维喷涂工程优质厂商综合实力深度解析

随着《建筑节能与可再生能源利用通用规范》GB 55015-2021的全面实施与“双碳”目标的持续推进,建筑围护结构的保温、防火与声学性能要求被提升至前所未有的高度。以某大型体育场馆改造项目为例,业主方不仅要求屋面与…

2026年成都石墨烯供热厂家甄选指南与优质企业推荐

随着国家“双碳”目标的持续推进与能源结构的深度转型,清洁、高效、智能的供暖方式正成为市场主流。石墨烯电采暖技术,凭借其电热转换效率高、发热均匀、节能环保、使用寿命长等显著优势,在成都及整个西南地区的民用…

2026年徐州商务车租赁市场深度评测:五家主流服务商横向对比

一、行业背景与评测引言 随着徐州作为淮海经济区中心城市的地位日益凸显,企业通勤、商务接待、团体旅游及大型活动出行需求持续攀升,推动了商务车租赁市场的蓬勃发展。据《2025-2026中国商务出行服务市场研究报告》显…