探索 C++23 std::to_underlying:枚举底层值获取的利器

文章目录

    • 引言
    • 基本概念
    • 作用
    • 使用示例
    • 与之前方法的对比
    • 在 C++23 中的意义
    • 总结

引言

在 C++ 的发展历程中,每一个新版本都带来了许多令人期待的新特性和改进,以提升代码的安全性、可读性和可维护性。C++23 作为其中的一个重要版本,也不例外。其中,std::to_underlying 这个工具函数便是 C++23 为开发者带来的一个实用礼物,它主要用于获取枚举(enum)的底层值。本文将深入探讨 std::to_underlying 的相关内容,包括其基本概念、作用、使用示例、与之前方法的对比以及在 C++23 中的意义。

基本概念

std::to_underlying 是 C++23 标准库中新增的一个实用工具函数,定义于头文件 <utility> 中。其函数原型如下:

emplate< class Enum >
constexpr std::underlying_type_t< Enum> to_underlying( Enum e ) noexcept ;

该函数的作用是将枚举类型转换为其底层类型,等价于 return static_cast<std::underlying_type_t<Enum>>(e);。这里的 Enum 是枚举类型,e 是要转换的枚举值,函数返回的是 Enum 的底层类型的整数值,从 e 转换而来。

作用

在实际编程中,我们经常会遇到需要将枚举值转换为其底层整数类型的情况。例如,当我们需要与一些无类型的 API 进行交互时,或者在进行日志记录、流操作等场景下,都可能需要获取枚举的底层值。在 std::to_underlying 出现之前,开发者通常会使用 static_cast 来完成这个转换,但这种方式存在一些问题。

使用 static_cast 进行枚举到其底层类型的转换,会使代码的可读性和可维护性变差。因为在代码中,static_cast 看起来就像普通的类型转换,很难快速识别出这是一个从强类型枚举到其底层值的转换。而且,当枚举类型的底层类型发生变化时(例如从有符号类型变为无符号类型),使用 static_cast 的代码可能会出现潜在的错误。而 std::to_underlying 的出现,正是为了解决这些问题,它提供了一种更安全、更清晰的方式来获取枚举的底层值。

使用示例

下面通过几个具体的示例来展示 std::to_underlying 的使用方法。

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <type_traits>
#include <utility>// 示例 1:不同枚举类型的底层类型验证
enum class E1 : char { e };
static_assert(std::is_same_v<char, decltype(std::to_underlying(E1::e))>);enum struct E2 : long { e };
static_assert(std::is_same_v<long, decltype(std::to_underlying(E2::e))>);enum E3 : unsigned { e };
static_assert(std::is_same_v<unsigned, decltype(std::to_underlying(E3::e))>);// 示例 2:实际输出枚举的底层值
int main()
{enum class ColorMask : std::uint32_t{red = 0xFF, green = (red << 8), blue = (green << 8), alpha = (blue << 8)};std::cout << std::hex << std::uppercase << std::setfill('0')<< std::setw(8) << std::to_underlying(ColorMask::red) << '\n'<< std::setw(8) << std::to_underlying(ColorMask::green) << '\n'<< std::setw(8) << std::to_underlying(ColorMask::blue) << '\n'<< std::setw(8) << std::to_underlying(ColorMask::alpha) << '\n';// 编译错误示例,不能直接将枚举赋值给底层类型变量// std::underlying_type_t<ColorMask> x = ColorMask::alpha; // 正确示例,使用 std::to_underlying 进行转换[[maybe_unused]]std::underlying_type_t<ColorMask> y = std::to_underlying(ColorMask::alpha); return 0;
}

在上述代码中,示例 1 通过 static_assert 验证了不同枚举类型使用 std::to_underlying 转换后的底层类型是否正确。示例 2 则实际输出了 ColorMask 枚举的各个值的底层类型,并且展示了直接将枚举赋值给底层类型变量会导致编译错误,而使用 std::to_underlying 则可以正确进行转换。

与之前方法的对比

std::to_underlying 出现之前,开发者通常会使用 static_cast 来将枚举转换为其底层类型。例如:

enum class MyEnum : int { Value1, Value2 };
int underlyingValue = static_cast<int>(MyEnum::Value1);

这种方式虽然可以实现功能,但存在一些缺点。首先,代码的可读性较差,从 static_cast 的使用中很难一眼看出这是在进行枚举到其底层类型的转换。其次,当枚举的底层类型发生变化时,需要手动修改 static_cast 中的目标类型,否则可能会导致潜在的错误。

而使用 std::to_underlying 则可以避免这些问题。std::to_underlying 明确地表示了这是一个将枚举转换为其底层类型的操作,提高了代码的可读性。并且,无论枚举的底层类型如何变化,std::to_underlying 都能正确工作,无需手动修改代码。例如:

enum class MyEnum : int { Value1, Value2 };
int underlyingValue = std::to_underlying(MyEnum::Value1);

即使 MyEnum 的底层类型从 int 变为其他类型,上述代码仍然可以正常工作。

在 C++23 中的意义

std::to_underlying 的引入是 C++ 语言不断发展和完善的体现。它符合现代 C++ 注重代码安全性、可读性和可维护性的设计理念。在 C++23 中,std::to_underlying 作为标准库的一部分,为开发者提供了一个统一、规范的方式来处理枚举到其底层类型的转换。

随着 C++ 标准的不断演进,枚举类型在 C++ 中的应用也越来越广泛。从 C++11 引入的枚举类(enum class)解决了传统枚举的命名冲突和隐式转换问题,到 C++17 允许使用大括号初始化基础类型,再到 C++20 引入的 using enum 语法,枚举类型的功能不断得到增强。而 std::to_underlying 的出现,进一步完善了枚举类型的使用场景,使得开发者在处理枚举时更加方便和安全。

总结

std::to_underlying 是 C++23 为开发者带来的一个实用工具函数,它为获取枚举的底层值提供了一种更安全、更清晰的方式。通过使用 std::to_underlying,可以提高代码的可读性和可维护性,避免因枚举底层类型变化而带来的潜在错误。在实际开发中,当需要将枚举转换为其底层类型时,建议优先使用 std::to_underlying。相信随着 C++23 的逐渐普及,std::to_underlying 会在更多的项目中得到广泛应用。

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

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

相关文章

WGDI-分析WGD及祖先核型演化的集成工具-文献精读126

WGDI: A user-friendly toolkit for evolutionary analyses of whole-genome duplications and ancestral karyotypes WGDI&#xff1a;一款面向全基因组重复事件与祖先核型演化分析的易用工具集 摘要 在地球上大多数主要生物类群中&#xff0c;人们已检测到全基因组复制&…

C# 方法(控制流和方法调用)

本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 控制流 方法包含了组成程序的…

「Mac畅玩AIGC与多模态16」开发篇12 - 多节点串联与输出合并的工作流示例

一、概述 本篇在输入变量与单节点执行的基础上,扩展实现多节点串联与格式化合并输出的工作流应用。开发人员将掌握如何在 Dify 工作流中统一管理输入变量,通过多节点串联引用,生成规范统一的最终输出,为后续构建复杂逻辑流程打下基础。 二、环境准备 macOS 系统Dify 平台…

解锁Windows异步黑科技:IOCP从入门到精通

在当今快节奏的数字化时代&#xff0c;软件应用对性能的追求可谓永无止境。无论是高并发的网络服务器&#xff0c;还是需要快速处理大量文件的桌面应用&#xff0c;都面临着一个共同的挑战&#xff1a;如何在有限的系统资源下&#xff0c;实现高效的数据输入输出&#xff08;I/…

Java学习手册:Spring 生态其他组件介绍

一、微服务架构相关组件 Spring Cloud 服务注册与发现 &#xff1a; Eureka &#xff1a;由 Netflix 开源&#xff0c;包含 Eureka Server 和 Eureka Client 两部分。Eureka Server 作为服务注册表&#xff0c;接收服务实例的注册请求并管理其信息&#xff1b;Eureka Client 负…

VMware Workstation 创建虚拟机并安装 Ubuntu 系统 的详细步骤指南

VMware Workstation 创建虚拟机并安装 Ubuntu 系统 的详细步骤指南 一、准备工作1. 下载 Ubuntu 镜像2. 安装 VMware Workstation 二、创建虚拟机1. 新建虚拟机向导2. 选择虚拟机配置类型3. 加载安装镜像4. 系统类型配置5. 虚拟机命名与存储6. 磁盘容量分配7. 硬件自定义&#…

串口的缓存发送以及缓存接收机制

#创作灵感# 在我们实际使用MCU进行多串口任务分配的时候&#xff0c;我们会碰到这样一种情况&#xff0c;即串口需要短间隔周期性发送数据&#xff0c;且相邻两帧之间需要间隔一段时间&#xff0c;防止连帧。我们常常需要在软件层面对串口的发送和接受做一个缓存的处理方式。 …

时间交织(TIADC)的失配误差校正处理(以4片1GSPS采样率的12bitADC交织为例讲解)

待写…有空再写&#xff0c;有需要的留言。 存在失配误差的4GSPS交织 校正完成后的4GSPS交织

Linux进程间通信(二)之管道1【匿名管道】

文章目录 管道什么是管道匿名管道用fork来共享管道原理站在文件描述符角度-深度理解管道站在内核角度-管道本质 接口实例代码管道特点管道的4种情况管道读写规则应用场景 管道 什么是管道 管道是Unix中最古老的进程间通信的形式。 我们把从一个进程连接到另一个进程的一个数…

Xilinx FPGA | 管脚约束 / 时序约束 / 问题解析

注&#xff1a;本文为 “Xilinx FPGA | 管脚约束 / 时序约束 / 问题解析” 相关文章合辑。 略作重排&#xff0c;未整理去重。 如有内容异常&#xff0c;请看原文。 Xilinx FPGA 管脚 XDC 约束之&#xff1a;物理约束 FPGA技术实战 于 2020-02-04 17:14:53 发布 说明&#x…

家用服务器 Ubuntu 服务器配置与 Cloudflare Tunnel 部署指南

Ubuntu 服务器配置与 Cloudflare Tunnel 部署指南 本文档总结了我们讨论的所有内容&#xff0c;包括 Ubuntu 服务器配置、硬盘扩容、静态 IP 设置以及 Cloudflare Tunnel 的部署步骤。 目录 硬盘分区与扩容设置静态 IPCloudflare Tunnel 部署SSH 通过 Cloudflare Tunnel常见…

分享5款开源、美观的 WinForm UI 控件库

前言 今天大姚给大家分享5款开源、美观的 WinForm UI 控件库&#xff0c;助力让我们的 WinForm 应用更好看。 WinForm WinForm是一个传统的桌面应用程序框架&#xff0c;它基于 Windows 操作系统的原生控件和窗体。通过简单易用的 API&#xff0c;开发者可以快速构建基于窗体…

PHP盲盒商城系统源码从零搭建部署:专业级开发与优化实践

【导语&#xff1a;技术驱动商业创新】 在2025年社交电商全面升级的浪潮下&#xff0c;基于PHP的盲盒系统凭借其高开发效率与低成本优势&#xff0c;成为中小企业的首选方案。本文将深度拆解盲盒源码从开发到部署的全流程技术细节&#xff0c;涵盖架构设计、性能优化与安全防护…

(33)VTK C++开发示例 ---图片转3D

文章目录 1. 概述2. CMake链接VTK3. main.cpp文件4. 演示效果 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;VTK开发 &#x1f448; 1. 概述 这是 VTK 测试 clipArt.tcl 的改编版本。 提供带有 2D 剪贴画的 jpg 文件&#xff0c;该示例将创建 3D 多边形数据模…

2025东三省B题深圳杯B题数学建模挑战赛数模思路代码文章教学

完整内容请看文章最下面的推广群 已经完成全部问题的代码和建模 一、问题一的模型构建与优化&#xff08;RGB颜色空间转换模型&#xff09; 基础模型&#xff08;线性映射模型&#xff09;/高斯过程回归模型&#xff08;GPR&#xff09;&#xff1a; 针对高清视频源&#xff0…

linux netlink实现用户态和内核态数据交互

1&#xff0c;内核态代码 #include <linux/module.h> #include <linux/netlink.h> #include <net/sock.h> #define NETLINK_TEST 31 struct sock *nl_sk NULL; static void nl_recv_msg(struct sk_buff *skb) { struct nlmsghdr *nlh; int pid; …

LeetCode:DP-多状态问题

简单 面试题 17.16. 按摩师 一个有名的按摩师会收到源源不断的预约请求&#xff0c;每个预约都可以选择接或不接。在每次预约服务之间要有休息时间&#xff0c;因此她不能接受相邻的预约。给定一个预约请求序列&#xff0c;替按摩师找到最优的预约集合&#xff08;总预约时间最…

Spring AOP---面向切面编程由认识到使用

1. AOP AOP(Aspect-Oriented Programming), 是一种思想, 面向切面编程。 在前文统一异常处理&#xff0c;统一结果返回就是使用了这一思想&#xff08;都是在集中处理某一类事情, 但又不影响原有代码的正常运行&#xff09;&#xff0c;但他们不是AOP&#xff0c;只是应用了这…

专题二十四:虚拟专用网络

一、VPN简介 VPN&#xff08;Virtual Personal Network&#xff09;即虚拟专用网&#xff0c;泛指通过VPN技术在公用网络上构建的虚拟专用网络。VPN用户在此虚拟网络中传输私网流量&#xff0c;在不改变网络现状的情况下实现安全、可靠的连接。其主要功能是在公用网络上建立专…

Milvus(12):分析器

1 分析器概述 在文本处理中&#xff0c;分析器是将原始文本转换为结构化可搜索格式的关键组件。每个分析器通常由两个核心部件组成&#xff1a;标记器和过滤器。它们共同将输入文本转换为标记&#xff0c;完善这些标记&#xff0c;并为高效索引和检索做好准备。 在 Milvus 中&a…